Copepod Collection

Copepods were collected at approximately weekly intervals from Lake Champlain (Burlington Fishing Pier). Plankton was collected from the top 3 meters using a 250 um mesh net.

# # Lake Champlain near Burlington, VT
# siteNumber = "04294500"
# ChamplainInfo = readNWISsite(siteNumber)
# parameterCd = "00010"
# startDate = "2023-01-01"
# endDate = "2024-5-20"
# #statCd = c("00001", "00002","00003", "00011") # 1 - max, 2 - min, 3 = mean
# 
# # Constructs the URL for the data wanted then downloads the data
# url = constructNWISURL(siteNumbers = siteNumber, parameterCd = parameterCd,
#                        startDate = startDate, endDate = endDate, service = "uv")
# 
# raw_temps = importWaterML1(url, asDateTime = T) %>%
#   mutate("date" = as.Date(dateTime),
#          "hour" = hour(dateTime)) %>%
#   select(dateTime, tz_cd, date, hour, degC = X_00010_00000)
# 
# temp_data =  raw_temps %>%
#   select(date, hour, "temp" = degC)
# 
# write.csv(temp_data, file = "./Output/Data/champlain_temps.csv", row.names = F)

Collections began in late May 2023. Several gaps are present, but collections have continued at roughly weekly intervals since then. Copepods from 48 collections were used to make a total of 1312 thermal limit measurements. Over this time period, collection temperatures ranged from 2.5 to 26.5°C.

There is substantial variation in thermal limits across the species collected. There is also some degree of variation within the species, with thermal limits increasing slightly during the summer.

## Daily values for the period examined by dataset
collection_conditions = temp_data %>%
  ungroup() %>% 
  group_by(date) %>% 
  summarise(mean_temp = mean(temp),
            med_temp = median(temp),
            var_temp = var(temp), 
            min_temp = min(temp), 
            max_temp = max(temp)) %>% 
  mutate("range_temp" = max_temp - min_temp,
         date = as.Date(date)) %>% 
  ungroup() %>%  
  filter(date >= (min(as.Date(full_data$collection_date)) - 7)) %>% 
  left_join(unique(select(full_data, collection_date, collection_temp)), by = join_by(date == collection_date))

## Mean female thermal limits for each species, grouped by collection
species_summaries = full_data %>%  
  #filter(sex == "female") %>% 
  group_by(sp_name, collection_date, collection_temp) %>%  
  summarise("mean_ctmax" = mean(ctmax),
            "sample_size" = n(),
            "ctmax_st_err" = (sd(ctmax) / sqrt(sample_size)),
            "ctmax_var" = var(ctmax), 
            "mean_size" = mean(size),
            "size_st_err" = (sd(size) / sqrt(sample_size)),
            "size_var" = var(size)) %>%  
  ungroup() %>% 
  complete(sp_name, collection_date) %>% 
  arrange(desc(sample_size))

adult_summaries = full_data %>%  
  filter(sex == "female") %>% 
  group_by(sp_name, collection_date, collection_temp) %>%  
  summarise("mean_ctmax" = mean(ctmax),
            "sample_size" = n(),
            "ctmax_st_err" = (sd(ctmax) / sqrt(sample_size)),
            "ctmax_var" = var(ctmax), 
            "mean_size" = mean(size),
            "size_st_err" = (sd(size) / sqrt(sample_size)),
            "size_var" = var(size)) %>%  
  ungroup() %>% 
  complete(sp_name, collection_date) %>% 
  arrange(desc(sample_size))


tseries_data = full_data %>% 
  mutate(sp_name = fct_reorder(sp_name, ctmax, .desc = T))

ggplot() + 
  geom_line(data = collection_conditions, 
            aes(x = as.Date(date), y = mean_temp),
            colour = "black", 
            linewidth = 1) + 
  geom_point(data = filter(tseries_data, species != "osphranticum_labronectum"), 
             aes(x = as.Date(collection_date), y = ctmax, colour = sp_name),
             size = 1.5, shape = 16, alpha = 0.9,
             position = position_jitter(width = 0, height = 0)) + 
    geom_point(data = filter(tseries_data, species == "osphranticum_labronectum"), 
             aes(x = as.Date(collection_date), y = ctmax, colour = sp_name),
             size = 2, shape = 16, alpha = 0.9,
             position = position_jitter(width = 0, height = 0)) + 
  scale_colour_manual(values = species_cols) + 
  guides(colour = guide_legend(override.aes = list(alpha = 1, size = 5))) + 
  labs(x = "Date", 
       y = "Temperature (°C)", 
       colour = "Species",
       size = "Sample Size") + 
  theme_matt() + 
  theme(legend.position = "right", 
        axis.text.x = element_text(angle = 320, hjust = 0, vjust = 0.5))


lake_temps = ggplot() + 
  geom_line(data = collection_conditions, 
            aes(x = as.Date(date), y = mean_temp),
            colour = "black", 
            linewidth = 1) + 
  labs(x = "Date", 
       y = "Temperature (°C)", 
       colour = "Species",
       size = "Sample Size") + 
  theme_matt() + 
  theme(legend.position = "right")

Temperatures observed at the time of collection closely resembled the maximum daily temperature from the temperature sensor data. Maximum temperature was used as a proxy instead of mean temperature as collections were usually made during afternoons or early evenings, just following the warmest part of the day.

collection_conditions %>% 
  drop_na(collection_temp) %>%  
  ggplot(aes(x = max_temp, y = collection_temp)) + 
  geom_abline(intercept = 0, slope = 1,
              linewidth = 1, colour = "grey") + 
  geom_point(size = 3) +
  scale_x_continuous(breaks = c(5,15,25)) + 
  scale_y_continuous(breaks = c(5,15,25)) + 
  labs(x = "Max. Temp. from Sensor (°C)",
       y = "Collection Temp. (°C)") + 
  theme_matt()

Size also varied, but primarily between rather than within species.

ggplot() + 
  geom_vline(data = unique(select(full_data, collection_date)), 
             aes(xintercept = as.Date(collection_date)),
             colour = "grey90",
             linewidth = 1) + 
  geom_line(data = collection_conditions, 
            aes(x = as.Date(date), y = mean_temp),
            colour = "black", 
            linewidth = 2) + 
  # geom_errorbar(data = species_summaries,
  #               aes(x = as.Date(collection_date), 
  #                   ymin = mean_ctmax - ctmax_st_err, ymax = mean_ctmax + ctmax_st_err,
  #                   colour = sp_name),
  #               position = position_dodge(width = 1),
  #               width = 5, linewidth = 1) + 
  geom_point(data = adult_summaries, 
             aes(x = as.Date(collection_date), y = mean_size * 40, colour = sp_name, size = sample_size),
             position = position_dodge(width = 1)) + 
  scale_colour_manual(values = species_cols) + 
  scale_y_continuous(
    name = "Temperature", # Features of the first axis
    sec.axis = sec_axis(~./40, name="Prosome Length (mm)"), # Add a second axis and specify its features
    breaks = c(0,5,10,15,20,25,30)
  ) + 
  labs(x = "Date", 
       y = "Temperature (°C)", 
       colour = "Species") + 
  theme_matt() + 
  theme(legend.position = "right")

sample_dates_plot = full_data %>%  
  filter(sp_name != "Osphranticum labronectum") %>% 
  mutate(sp_name = as.factor(sp_name),
         sp_name = fct_reorder(sp_name, ctmax)) %>% 
  ggplot(aes(x = lubridate::as_date(collection_date), 
             y = sp_name, fill = sp_name)) + 
  # geom_vline(xintercept = as_date(
  #   c("2023-05-01",
  #     "2023-09-01",
  #     "2024-01-01",
  #     "2024-05-01")),
  #   colour = "grey",
  #   linewidth = 1) + 
  geom_density_ridges(bandwidth = 30,
                      jittered_points = TRUE, 
                      point_shape = 21,
                      point_size = 1,
                      point_colour = "grey30",
                      point_alpha = 0.8,
                      alpha = 0.8,
                      position = position_points_jitter(
                        height = 0.1, width = 0)) + 
  scale_fill_manual(values = species_cols) + 
  scale_x_date(date_breaks = "3 months",
               date_labels = "%b") + 
  coord_cartesian(xlim = lubridate::as_date(c("2023-06-08", "2024-05-08"))) + 
  labs(x = "Day of Year", 
       y = "Species") + 
  theme_matt() + 
  #theme_ridges(grid = T) + 
  theme(legend.position = "none",
        axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))

The samples captured the broad seasonal changes in calanoid copepod community composition in the lake. We note, however, that rare species (e.g. Senecella and Limnocalanus) were often preferentially sampled, so are over-represented in the data set.

Throughout the season, the prevalence of various unidentified pathogens also varied, with very little infection observed during the Winter and Spring.

pathogen_cols = c("no" = "grey95", "cloudy" = "honeydew3", "spot" = "antiquewhite3", "other" = "tomato3")

full_data %>% 
  select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>% 
  group_by() %>% 
  filter(sex != "juvenile") %>% 
  group_by(collection_date) %>% 
  count(pathogen) %>% 
  filter(pathogen != "uncertain") %>% 
  pivot_wider(id_cols = "collection_date", 
              names_from = pathogen, 
              values_from = n,
              values_fill = 0) %>% 
  mutate(total = sum(no, cloudy, spot, other)) %>% 
  pivot_longer(cols = c(no, cloudy, spot, other),
               names_to = "pathogen", 
               values_to = "count") %>% 
  mutate(percent = count/total,
         collection_date = lubridate::as_date(collection_date),
         pathogen = fct_relevel(pathogen, "no", "cloudy", "spot", "other")) %>% 
  ggplot(aes(x = collection_date, y = percent, fill = pathogen)) + 
  geom_area() + 
  scale_fill_manual(values = pathogen_cols) + 
  scale_y_continuous(breaks = c(0,1)) + 
  labs(x = "Collection Date", 
       y = "Proportion", 
       fill = "Pathogen") + 
  theme_minimal(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.ticks = element_line())

The transparent bodies of these copepods also allowed us to examine seasonal patterns in lipid reserves and in the production of eggs. Maturing oocytes are visible in female copepods before they are released. There was no strong seasonal cycle in the production of these eggs in any species, and instead, females were reproductively active throughout their respective seasons of occurence.

dev_eggs_cols = c("no" = "grey95", "yes" = "lightblue3")

full_data %>% 
  select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>% 
  group_by(sp_name) %>% 
  filter(sex != "juvenile") %>% 
  group_by(sp_name, collection_date) %>% 
  count(dev_eggs) %>% 
  filter(dev_eggs != "uncertain") %>% 
  pivot_wider(id_cols = c("collection_date", "sp_name"), 
              names_from = dev_eggs, 
              values_from = n,
              values_fill = 0) %>% 
  mutate(total = sum(no, yes)) %>% 
  pivot_longer(cols = c(no, yes),
               names_to = "dev_eggs", 
               values_to = "count") %>% 
  mutate(percent = count/total,
         collection_date = lubridate::as_date(collection_date),
         dev_eggs = fct_relevel(dev_eggs, "no", "yes")) %>% 
  ungroup() %>% 
  complete(collection_date, nesting(sp_name, dev_eggs), fill = list(percent = 1)) %>% 
  mutate(percent = if_else(is.na(total) & dev_eggs == "yes", 0, percent)) %>% 
  ggplot(aes(x = collection_date, y = percent, fill = dev_eggs)) + 
  facet_wrap(sp_name~., ncol = 1) + 
  geom_area() + 
  scale_fill_manual(values = dev_eggs_cols) + 
  scale_y_continuous(breaks = c(0,1)) + 
  labs(x = "Collection Date", 
       y = "Proportion", 
       fill = "Developing \nEggs") + 
  theme_minimal(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.ticks = element_line())

The presence of lipids varied across species, with only L. minutus, L. sicilis, and Limnocalanus regularly possessing lipid stores.

lipid_cols = c("no" = "grey95", "yes" = "sienna2")

full_data %>% 
  select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>% 
  group_by(sp_name) %>% 
  filter(sex != "juvenile") %>% 
  group_by(sp_name, collection_date) %>% 
  count(lipids) %>% 
  filter(lipids != "uncertain") %>% 
  pivot_wider(id_cols = c("collection_date", "sp_name"), 
              names_from = lipids, 
              values_from = n,
              values_fill = 0) %>% 
  mutate(total = sum(no, yes)) %>% 
  pivot_longer(cols = c(no, yes),
               names_to = "lipids", 
               values_to = "count") %>% 
  mutate(percent = count/total,
         collection_date = lubridate::as_date(collection_date),
         lipids = fct_relevel(lipids, "no", "yes")) %>% 
  ungroup() %>% 
  complete(collection_date, nesting(sp_name, lipids), fill = list(percent = 1)) %>% 
  mutate(percent = if_else(is.na(total) & lipids == "yes", 0, percent)) %>% 
  ggplot(aes(x = collection_date, y = percent, fill = lipids)) + 
  facet_wrap(sp_name~., ncol = 1) + 
  geom_area() + 
  scale_fill_manual(values = lipid_cols) + 
  scale_y_continuous(breaks = c(0,1)) + 
  labs(x = "Collection Date", 
       y = "Proportion", 
       fill = "Lipids\nPresent") + 
  theme_minimal(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.ticks = element_line())

Temperature Variability

Lake Champlain is highly seasonal, with both average temperatures and temperature variability changing throughout the year. These patterns in the experienced thermal environment may drive the observed variation in copepod thermal limits. However, the time period affecting copepod thermal limits is unknown. Depending the on the duration of time considered, there are large changes in the experienced environment, in particular regarding the temperature range and variance. Consider for example three time periods: the day of collection, one week prior to collection, and four weeks prior to collection. While the overall pattern is similar, we can see that, unsurprisingly, considering longer periods of time results in larger ranges and slightly changes the pattern of variance experienced.

## Defining the function to get predictor values for periods of different lengths
get_predictors = function(daily_values, raw_temp, n_days){
  prefix = str_replace_all(xfun::numbers_to_words(n_days), pattern = " ", replacement = "-")
  
  mean_values = daily_values %>% 
    ungroup() %>% 
    mutate(mean_max = slide_vec(.x = max_temp, .f = mean, .before = n_days, .complete = T),
           mean_min = slide_vec(.x = min_temp, .f = mean, .before = n_days, .complete = T),
           mean_range = slide_vec(.x = range_temp, .f = mean, .before = n_days, .complete = T)) %>% 
    select(date, mean_max, mean_min, mean_range) %>% 
    rename_with( ~ paste(prefix, "day", .x, sep = "_"), .cols = c(-date))
  
  period_values = raw_temp %>% 
    mutate(mean = slide_index_mean(temp, i = date, before = days(n_days), 
                                   na_rm = T),
           max = slide_index_max(temp, i = date, before = days(n_days), 
                                 na_rm = T),
           min = slide_index_min(temp, i = date, before = days(n_days),
                                 na_rm = T),
           med = slide_index_dbl(temp, .i = date, .before = days(n_days), 
                                 na_rm = T, .f = median),
           var = slide_index_dbl(temp, .i = date, .before = days(n_days), 
                                 .f = var),
           range = max - min) %>%  
    select(-temp) %>%  
    distinct() %>% 
    rename_with( ~ paste(prefix, "day", .x, sep = "_"), .cols = c(-date))%>% 
    inner_join(mean_values, by = c("date")) %>%  
    drop_na()
  
  return(period_values)
}

Organisms are unlikely to acclimate instantaneously to changes in temperature. To explore the potential temporal window these copepods are responding to, we examined the correlation between thermal limits and summaries of the thermal environment over different periods of time. For each species (inclusive of all sexes and stages), we examined the correlation between CTmax and one of nine representations of the thermal environment calculated for periods of time from 1 to 60 days before collection. These parameters include the overall maximum, minimum, median, and mean temperature for the period of time, the temperature range and variance during this time, and the mean daily temperature maximum, minimum, and range. We also examined the correlation between CTmax and the temperature recorded at the time of collection.

Shown below are the correlation coefficients for these relationships. Each facet shows the relationship for a different parameter, plotted against the duration of the time period before collection.

corr_vals %>% 
  mutate(parameter = fct_relevel(parameter, c("min", "max", "range",
                                              "mean", "med", "var",
                                              "mean_min", "mean_max", "mean_range"))) %>% 
  ggplot(aes(x = duration, y = correlation, colour = sp_name)) + 
  facet_wrap(.~parameter) + 
  geom_hline(yintercept = 0) + 
  geom_point(size = 0.9) + 
  geom_line(linewidth = 1.5) + 
  scale_colour_manual(values = species_cols) + 
  labs(x = "Duration (days)",
       y = "Correlation", 
       colour = "Species") + 
  theme_matt_facets()

This table contains the top three factors for each species (based on correlation coefficient).

Shown here is a graphical summary of the duration of the best predictors for each species. Note that for the two Leptodiaptomids, collection temperature had the largest correlation coefficient so duration is zero. This representation highlights that there is variation across the community not only in the potential driver (e.g. minimum vs. maximum temperatures) but also in the duration of time. This variation is not grouped by season (the winter and summer communities both have representative species apparently responding to short and long durations).

duration_plot = corr_vals %>%  
  filter(sig == "Sig.") %>% 
  drop_na(correlation) %>% 
  group_by(sp_name) %>%
  arrange(desc(correlation)) %>% 
  slice_head(n = 1) %>% 
  ungroup() %>% 
  mutate("num" = row_number(), 
         sp_name = fct_reorder(sp_name, duration, .fun = mean, .desc = T)) %>% 
  arrange(sp_name) %>% 
  select("Species" = sp_name, "Predictor" = parameter, "Duration" = duration, "Correlation" = correlation, num) %>% 
  ggplot(aes(x = Species, y = Duration, fill = Predictor, group = num)) + 
  geom_bar(stat = "identity", width = 0.5, position = position_dodge(width = 0.6),
           colour = "black") + 
  scale_fill_manual(values = c("coll_temp" = "black", "max" = "white", "min" = "grey")) + 
  labs(x = "", 
       y = "Duration \n(days)") + 
  theme_matt() + 
  theme(axis.text.x = element_blank())
correlation_coef_plot = corr_vals %>%  
  filter(sig == "Sig." | parameter == "coll_temp") %>% 
  drop_na(correlation) %>% 
  group_by(sp_name) %>%
  filter(parameter == "coll_temp" | correlation == max(correlation)) %>% 
  arrange(sp_name, parameter) %>% 
  mutate("num" = row_number()) %>% 
  select("Species" = sp_name, "Predictor" = parameter, "Duration" = duration, "Correlation" = correlation, num) %>% 
  mutate(Predictor = if_else(Predictor == "coll_temp", Predictor, "best")) %>% 
  ungroup() %>% 
  mutate(Species = fct_reorder(Species, Duration, .fun = max, .desc = T)) %>% 
  ggplot(aes(x = Species, y = Correlation, fill = Predictor, group = num)) + 
  geom_bar(stat = "identity", width = 0.5, position = position_dodge(width = 0.6),
           colour = "black") + 
  labs(y = "Correlation \nCoefficient",
       fill = "Correlate") +
  scale_fill_manual(values = c("coll_temp" = "black", "best" = "white")) + 
  scale_y_continuous(breaks = c(0, 1), limits = c(0,1)) +
  theme_matt() + 
  theme(axis.text.x = element_text(angle = 300, hjust = 0, vjust = 0.5))

ggarrange(duration_plot, correlation_coef_plot, nrow = 2, legend = "right", labels = "AUTO",
          heights = c(0.4, 0.6))

Trait Variation

Shown below are the clutch size distributions for the three diaptomiid species, which produce egg sacs that allow for easy quantification of fecundity.

full_data %>%  
  drop_na(fecundity) %>%  
  ggplot(aes(x = fecundity, fill = sp_name_sub)) + 
  facet_wrap(.~sp_name_sub, ncol = 1) + 
  geom_histogram(binwidth = 2) + 
  scale_fill_manual(values = species_cols) + 
  labs(x = "Fecundity (# Eggs)") +
  theme_matt_facets() + 
  theme(legend.position = "none")

One of the main aims of this project is to examine the patterns and processes driving variation in upper thermal limits across these species of copepods.

Variation with temperature

We expect one of the primary drivers of copepod thermal limits to be temperature, as individuals acclimate to seasonal changes. Shown below are the seasonal patterns of when copepods were included in CTmax measurements (a proxy for the season of occurrence), and thermal limits for each species plotted against the temperature at the time of collection. We generally see an increase in thermal limits with increasing collection temperature.

sp_ctmax_temp = full_data %>% 
  filter(sp_name != "Osphranticum labronectum") %>% 
  mutate(sp_name = as.factor(sp_name),
         sp_name = fct_reorder(sp_name, ctmax, .desc = T)) %>% 
  ggplot(aes(x = collection_temp, y = ctmax, colour = sp_name)) + 
  facet_wrap(sp_name~.) + 
  geom_smooth(method = "lm", se = F, linewidth = 1.5, colour = "grey30") + 
  geom_point(size = 2, alpha = 0.4) + 
  labs(x = "Collection Temp. (°C)", 
       y = "CTmax (°C)") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "none")

The interaction between seasonal changes in temperature and the acclimation of thermal limits likely affects vulnerability of each species to warming. Shown below are warming tolerance values for each species, calculated as the difference between individual CTmax and the temperature at the time of collection. All species maintained some degree of buffer between environmental temperatures and upper thermal limits, but L. minutus appears to approach its upper thermal limit during the warmest collections during the summer.

Also shown below is the relationship between fecundity (the number of eggs contained in a clutch) for the three diaptomid species. For the two Leptodiaptomus species, there is no relationship between clutch size and temperature, while there appears to be a general increase in clutch size with temperature in the Skistodiaptomus species.


wt_temp = full_data %>% 
  filter(sp_name != "Osphranticum labronectum") %>% 
  ggplot(aes(x = collection_temp, y = warming_tol, colour = sp_name)) + 
  geom_point(size = 3,
             alpha = 0.3) + 
  geom_smooth(method = "lm", linewidth = 3) +
  labs(x = "Collection Temperature (°C)", 
       y = "Warming Tolerance (°C)",
       colour = "Species")  + 
  ylim(0,30) + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "none")

eggs_temp = full_data %>% 
  filter(sp_name != "Osphranticum labronectum") %>% 
  ggplot(aes(x = collection_temp, y = fecundity, colour = sp_name)) + 
  geom_point(size = 3,
             alpha = 0.3) + 
  geom_smooth(method = "lm", linewidth = 3) +
  labs(x = "Collection Temperature (°C)", 
       y = "Fecundity (# Eggs)",
       colour = "Species")  + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

ggarrange(wt_temp, eggs_temp, 
          common.legend = T, legend = "right", labels = "AUTO")

# Copepods spent several days in lab during experiments. Shown below are the CTmax residuals (taken from a model of CTmax against collection temperature) plotted against the time spent in lab before measurements were made. Individual regressions are shown for the residuals against days in lab for each collection. We can see clearly that thermal limits are fairly stable over time. 


# ggplot(ctmax_resids, aes(x = days_in_lab, y = resids, colour = sp_name, group = collection_date)) + 
#   facet_wrap(sp_name~.) + 
#   geom_point(size = 4, alpha = 0.5) + 
#   geom_smooth(method = "lm", se = F, linewidth = 1) + 
#   #scale_x_continuous(breaks = c(0:5)) + 
#   labs(x = "Days in lab", 
#        y = "CTmax Residuals") + 
#   scale_colour_manual(values = species_cols) + 
#   theme_matt_facets() + 
#   theme(legend.position = "none")

model_data = full_data %>%  
  drop_na(size, ctmax) %>%  
  filter(sp_name != "Osphranticum labronectum") %>% 
  mutate(temp_cent = scale(collection_temp, center = T, scale = F),
         size_cent = scale(size, center = T, scale = F))

minimal.model = lme4::lmer(data = model_data,
                           ctmax ~ sp_name + sex + temp_cent +
                             (1|days_in_lab))

full.model = lme4::lmer(data = model_data,
                        ctmax ~ sp_name*sex*temp_cent +
                          (1|days_in_lab))

drop1(full.model, test = "Chisq")
## Single term deletions
## 
## Model:
## ctmax ~ sp_name * sex * temp_cent + (1 | days_in_lab)
##                       npar    AIC    LRT Pr(Chi)  
## <none>                     5280.1                 
## sp_name:sex:temp_cent   10 5281.0 20.887  0.0219 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

performance::test_performance(minimal.model, full.model)
## Name          |   Model |    BF | df | df_diff |   Chi2 |      p
## ----------------------------------------------------------------
## minimal.model | lmerMod |       | 11 |         |        |       
## full.model    | lmerMod | 0.001 | 38 |   27.00 | 180.70 | < .001
## Models were detected as nested (in terms of fixed parameters) and are compared in sequential order.
performance::check_model(full.model)


car::Anova(full.model, type = "III")
## Analysis of Deviance Table (Type III Wald chisquare tests)
## 
## Response: ctmax
##                          Chisq Df Pr(>Chisq)    
## (Intercept)           4619.014  1  < 2.2e-16 ***
## sp_name                344.724  5  < 2.2e-16 ***
## sex                     51.233  2  7.495e-12 ***
## temp_cent               53.731  1  2.299e-13 ***
## sp_name:sex             10.611 10    0.38866    
## sp_name:temp_cent       39.512  5  1.873e-07 ***
## sex:temp_cent           31.961  2  1.147e-07 ***
## sp_name:sex:temp_cent   20.616 10    0.02393 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

sp_ctmax = emmeans::emmeans(full.model, specs = "sp_name") %>% 
  data.frame() %>% 
  select(sp_name, "species_ctmax" = emmean)

model_coefs = emmeans::emtrends(full.model, var = "temp_cent", specs = "sp_name") %>% 
  data.frame() %>% 
  inner_join(sp_ctmax) 

ctmax_resids = model_data %>% 
  mutate(resids = residuals(full.model))

#write.csv(model_coefs, "Output/Data/ARR_data.csv")
arr_combined = synth_arr %>%
  filter(measure == "upper" & mean_lim > 20) %>% 
  select("group" = genus, arr, mean_lim) %>% 
  mutate("dataset" = "synthesis") %>% 
  bind_rows(
    select(model_coefs, "group" = sp_name, 'arr' = temp_cent.trend, 'mean_lim' = species_ctmax)
  ) %>% 
  mutate(dataset = if_else(is.na(dataset), "new data", "synthesis"),
         group = fct_reorder(group, arr, .desc = T))


ggplot(arr_combined, aes(x = mean_lim, y = arr)) + 
  geom_smooth(method = "lm", se = F, 
              linewidth = 2, colour = "grey30") + 
  geom_point(data = filter(arr_combined, dataset != "new data"), 
             size = 3, colour = "black", shape = 1, stroke = 1.4) + 
  geom_point(data = filter(arr_combined, dataset == "new data"),
             aes(colour = group), 
             size = 4.5) + 
  scale_colour_manual(values = species_cols) + 
  labs(x = "Thermal Limit", 
       y = "ARR", 
       colour = "Species") +
  theme_matt() + 
  theme(legend.position = "right")

Sex and stage variation in thermal limits

Previous sections have generally lumped juvenile, female, and male individuals together. There may be important stage- or sex-specific differences in CTmax though. For all species but Osphranticum, we have measurements for individuals in different stages and of different sexes.

sex_sample_sizes = full_data %>%  
  group_by(sp_name, sex) %>%  
  summarise(num = n()) %>%  
  pivot_wider(id_cols = sp_name,
              names_from = sex, 
              values_from = num,
              values_fill = 0) %>% 
  select("Species" = sp_name, "Juvenile" = juvenile, "Female" = female, "Male" = male)

knitr::kable(sex_sample_sizes, align = "c")
Species Juvenile Female Male
Epischura lacustris 37 45 20
Leptodiaptomus minutus 12 273 39
Leptodiaptomus sicilis 31 356 95
Limnocalanus macrurus 4 43 39
Osphranticum labronectum 0 1 0
Senecella calanoides 13 21 8
Skistodiaptomus sp 15 232 28

Across group comparisons show that there are generally no differences in thermal limits (represented here as the residuals from a CTmax ~ collection_temp x species linear regression), with the exception of Senecella males, which may have lower thermal limits (although sample sizes are very small in this group).

# ctmax_resids %>% 
#   filter(sp_name != "Osphranticum labronectum") %>% 
#   ggplot(aes(x = sex, y = resids, colour = sp_name)) + 
#   facet_wrap(sp_name~.) + 
#   geom_jitter(width = 0.1, alpha = 0.5) + 
#   geom_boxplot(width = 0.4, fill = NA, colour = "black", 
#                linewidth = 1, outlier.colour = NA) + 
#   scale_colour_manual(values = species_cols) + 
#   theme_matt_facets()
model2_data = model_data %>% 
  filter(sex == "female", 
         pathogen != "uncertain", 
         dev_eggs != "uncertain", 
         lipids != "uncertain") %>% 
  mutate(pathogens = fct_relevel(pathogen, "no", "spot", "cloudy", "other"))

other_factor_model = lmer(data = model2_data, 
                          ctmax~sp_name * collection_temp + dev_eggs + pathogen + lipids + (1|days_in_lab))

drop1(other_factor_model, scope = ~., test = "Chisq")
## Single term deletions
## 
## Model:
## ctmax ~ sp_name * collection_temp + dev_eggs + pathogen + lipids + 
##     (1 | days_in_lab)
##                         npar    AIC     LRT   Pr(Chi)    
## <none>                       3601.6                      
## sp_name                    5 3804.2 212.619 < 2.2e-16 ***
## collection_temp            0 3601.6   0.000              
## dev_eggs                   1 3602.0   2.391    0.1220    
## pathogen                   3 3629.4  33.832 2.149e-07 ***
## lipids                     1 3600.0   0.416    0.5189    
## sp_name:collection_temp    5 3635.7  44.139 2.171e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

reduced_factors_model = lmer(data = model2_data, 
                          ctmax~sp_name * collection_temp + pathogen + (1|days_in_lab))

performance::check_model(reduced_factors_model)


car::Anova(reduced_factors_model, type = "III")
## Analysis of Deviance Table (Type III Wald chisquare tests)
## 
## Response: ctmax
##                           Chisq Df Pr(>Chisq)    
## (Intercept)             570.328  1  < 2.2e-16 ***
## sp_name                 234.027  5  < 2.2e-16 ***
## collection_temp          72.589  1  < 2.2e-16 ***
## pathogen                 35.282  3  1.062e-07 ***
## sp_name:collection_temp  43.558  5  2.847e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
emmeans::emmeans(reduced_factors_model, spec = "pathogen") %>% emmeans::contrast(method="trt.vs.ctrl",ref="no") %>% plot() + 
  geom_vline(xintercept = 0) + 
  labs(x = "Difference (°C)", 
       y = "Comparison") + 
    theme_matt()

Trait Correlations and Trade-offs

A relationship between size and upper thermal limits has been suggested in a wide range of other taxa. Shown below are the measured upper thermal limits plotted against prosome length. The overall relationship (inclusive of all species) is shown as the black line in the background. Regressions for each individual species are also shown. Across the entire assemblage, there is a strong decrease in thermal limits with increasing size.

full_data %>% 
  #filter(sex == "female") %>%  
  ggplot( aes(x = size, y = ctmax, colour = sp_name)) + 
  geom_point(size = 2, alpha = 0.3) + 
  geom_smooth(data = full_data, 
              aes(x = size, y = ctmax),
              method = "lm", 
              colour ="black", 
              linewidth = 2.5) + 
  labs(x = "Length (mm)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

Shown here is the relationship for each species individually.

full_data %>% 
  #filter(sex == "female") %>%  
  group_by(sp_name) %>% filter(n() >2) %>% filter(!str_detect(sp_name, pattern = "kindti")) %>% 
  ggplot( aes(x = size, y = ctmax, colour = sp_name)) + 
  facet_wrap(sp_name~., scales = "free", nrow = 2) + 
  geom_point(size = 2, alpha = 0.8) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  labs(x = "Length (mm)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "none")

Shown below is the relationship between mean size and mean thermal limits for females of each species. We see that larger species within the community tend to have a lower thermal limit than smaller species.

full_data %>% 
  group_by(sp_name, sex) %>% 
  summarize(mean_ctmax = mean(ctmax, na.rm = T),
            mean_size = mean(size, na.rm = T)) %>% 
  #filter(sex == "female") %>% 
  ggplot(aes(x = mean_size, y = mean_ctmax)) + 
  geom_smooth(method = "lm", se = F, linewidth = 2, colour = "black") + 
  geom_point(aes(colour = sp_name, shape = sex),
             size = 5) + 
  labs(x = "Length (mm)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

Shown here is the relationship between fecundity and size, showing the classic pattern of increasing egg production with increasing size.

size_fecund_plot = ctmax_resids %>%  
  drop_na(fecundity) %>% 
  ggplot(aes(x = size, y = fecundity, colour = sp_name)) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  geom_point(size = 2, alpha = 0.5) + 
  labs(x = "Prosome length (mm)", 
       y = "Fecundity (# Eggs)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

Individuals may also allocate energy to different fitness related traits, prioritizing reproductive output over environmental tolerance, for example. Shown below is the relationship between CTmax residuals (again, controlling for the effects of collection temperature) against fecundity. We can see clearly that individuals with increased fecundity are not decreasing thermal limits, suggesting that there is no energetic trade-off between these traits.

ctmax_fecund_plot = ctmax_resids %>%  
  drop_na(fecundity) %>% 
  ggplot(aes(x = resids, y = fecundity, colour = sp_name)) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  geom_point(size = 2, alpha = 0.5) + 
  labs(x = "CTmax Residuals (°C)", 
       y = "Fecundity (# Eggs)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

ggarrange(size_fecund_plot, ctmax_fecund_plot, ncol = 1, common.legend = T, labels = "AUTO", legend = "right")

Previous studies have shown that the magnitude of the size-fecundity correlation may be environmentally-dependent. This is not visible is the data from these collections.

corr_data = full_data %>% 
  drop_na(fecundity) %>% 
  filter(sp_name %in% c("Leptodiaptomus sicilis",
                        "Leptodiaptomus minutus", 
                        "Skistodiaptomus sp")) %>%  
  group_by(collection_date, collection_temp, sp_name) %>% 
  summarise(size_fec_corr = cor(size, fecundity),
            n = n(),
            mean_fecundity = mean(fecundity)) %>% 
  filter(n >= 3) %>% 
  ungroup() %>%  
  group_by(sp_name) %>% 
  mutate(temp_cent = scale(collection_temp, scale = F))

ggplot(corr_data, aes(x = temp_cent, y = size_fec_corr, colour = sp_name)) + 
  facet_wrap(sp_name~., nrow = 3) + 
  geom_hline(yintercept = 0) +
  geom_point(size = 3) + 
  geom_smooth(method = "lm", linewidth = 2) + 
  scale_color_manual(values = species_cols) + 
  labs(x = "Temperature (centered)", 
       y = "Correlation Coefficient") + 
  coord_cartesian(ylim = c(-1, 1)) +
  theme_matt_facets() + 
  theme(legend.position = "none")


# ggplot(corr_data, aes(x = size_fec_corr)) +
#     facet_wrap(sp_name~., nrow = 3) +
#   geom_histogram(binwidth = 0.2)

Other patterns in variation

Leptodiaptomus sicilis is the most abundant species during the winter. There was a large shift in the size of mature females towards the end of December. These large and small individuals are the same species (confirmed via COI sequencing), suggesting this shift may instead reflect a transition from one generation to another. This size difference may be caused by differences in the developmental environments. For example, individuals developing in January grow up at very low temperatures, and therefore may reach larger sizes. These individuals over-summer in deep waters, then re-emerge in October and produce a new generation. Water temperatures are still fairly high through November, which results in a generation of smaller individuals. These individuals mature in time to produce a new generation in January.

full_data %>%  
  filter(sp_name == "Leptodiaptomus sicilis") %>% 
  filter(sex != "juvenile") %>% 
  group_by(collection_date) %>% 
  mutate(size_center = scale(size, center = T, scale = F)) %>% 
  ggplot(aes(y = factor(collection_date), x = size, fill = collection_temp)) + 
  facet_wrap(sex~.) + 
  geom_density_ridges(bandwidth = 0.04) + 
  geom_vline(xintercept = 0.89) + 
  labs(x = "Size (mm)",
       y = "Date", 
       fill = "Coll. Temp. (°C)") + 
  theme_matt() + 
  theme(legend.position = "right",
        axis.text.y = element_text(size = 12))

A similar, but less distinct pattern can be observed in L. minutus individuals as well.

full_data %>%  
  filter(sp_name == "Leptodiaptomus minutus") %>% 
  filter(sex != "juvenile") %>% 
  ggplot(aes(y = factor(collection_date), x = size, fill = collection_temp)) + 
  facet_wrap(sex~.) + 
  geom_density_ridges(bandwidth = 0.04) + 
  geom_vline(xintercept = 0.69) + 
  labs(x = "Size (mm)",
       y = "Date", 
       fill = "Coll. Temp. (°C)") + 
  coord_cartesian(xlim = c(0.5,0.9)) + 
  theme_matt() + 
  theme(legend.position = "right",
        axis.text.y = element_text(size = 12))

Distribution Lag Non-Linear Model (DLNM approach)

Distributed lag models examine a response variable, measured at multiple time points, as a function of the lagged occurrence of some predictor variable (response y at time t as a function of predictor x(t-lag). This method utilizes a bi-dimensional dose-lag-response function, which essentially examines not only the dose effect, but the effect of the timing of the dose.

# Run this code, save the product, and then just read in the temp lag data object. Takes too long to run each time this document is knit. 

# lag_temps = temp_data %>%
#   group_by(date, hour) %>%
#   summarize("mean_temp" = mean(temp, na.rm = T)) %>%
#   ungroup() %>%
#   mutate(point_num = row_number())
# 
# uniq_days = length(unique(lag_temps$date))
# 
# g = gam(mean_temp ~ s(point_num, bs="cr", k=uniq_days + 10),
#     method = "REML",
#     data = lag_temps)
# 
# points = seq(1, nrow(lag_temps), length.out = length(lag_temps$hour))
# 
# df.res = df.residual(g)
# 
# pred_temps = predict(g, newdata = lag_temps, type = "response", se.fit = TRUE)
# 
# lag_temps = lag_temps %>%
#   mutate(trend_T = pred_temps$fit,
#          trend_se = pred_temps$se.fit,
#          temp_diff = mean_temp - trend_T)
# 
# write.csv(lag_temps, file = "./Output/Data/lag_temps.csv", row.names = F)

dlnm_data = full_data %>%  
  filter(sex == "female") %>% 
  filter(sp_name %in% c(
    "Leptodiaptomus sicilis",
    "Leptodiaptomus minutus"
  )) %>% 
  select(collection_date, collection_temp, sp_name, ctmax) %>% 
  group_by(collection_date, collection_temp, sp_name) %>%  
  summarise(mean_ctmax = mean(ctmax, na.rm = T),
            sample = n())

temp_data %>% 
  group_by(date) %>% 
  summarise(mean_temp = mean(temp),
            max_temp = max(temp, na.rm = T)) %>% 
  right_join(dlnm_data, by = join_by("date" == "collection_date")) %>% 
  ggplot(aes(x = max_temp, y = mean_ctmax)) + 
  facet_wrap(.~sp_name) + 
  geom_smooth(method = "gam") + 
  geom_point() + 
  labs(x = "Max Daily Temp. (°C)",
       y = "Mean CTmax (°C)") + 
  theme_matt_facets() + 
  theme(strip.text.x = element_text(size = 12))


sp_list = unique(dlnm_data$sp_name)

for(lag_species in sp_list){
  
  dlnm_data_sp = dlnm_data %>% 
    filter(sp_name == lag_species)
  
  # We need to estimate a matrix of exposure histories for each observation. This contains the series of exposures at each lag (l) for each of the n observations, constrained between l0 (minimum lag) and L (max lag). 
  
  dates = dlnm_data_sp$collection_date # For each of these dates, make a vector of the past 30 days (including the day of collection). NOTE: Don't use 'unique' dates here since some collections had multiple species
  
  exp_hist_z = data.frame()
  exp_hist_trend = data.frame()
  
  for(d in dates){
    
    history = lag_temps %>% 
      filter(date <= d & date > d - 10) %>% 
      arrange(desc(date), desc(hour)) %>% 
      mutate(lag = row_number() - 1) %>% 
      select(lag, mean_temp, temp_diff)
    
    z_vec = scale(history$mean_temp)[,1]
    names(z_vec) = history$lag
    
    trend_vec = history$temp_diff
    names(trend_vec) = history$lag
    
    exp_hist_z = bind_rows(exp_hist_z, z_vec)
    exp_hist_trend = bind_rows(exp_hist_trend, trend_vec)
    
  }
  
  #print(max(exp_hist_trend, na.rm = T))
  
  # The cross-basis function from dlnm will use the class of the x parameter to determine what to do. In our case, we need to provide it with the matrix of exposure histories for reach observation (row) and lag (column). 
  
  cb_temps = crossbasis(exp_hist_trend, lag = c(0,dim(exp_hist_trend)[2]-1), 
                        argvar =list(fun="cr",df=3), 
                        arglag=list(fun="cr",df=3,intercept=T))
  
  #summary(cb_temps)
  
  penalized_mat <- cbPen(cb_temps)
  
  #fitting GAM
  lag.gam = gam(data = dlnm_data_sp, 
                mean_ctmax ~ collection_temp + cb_temps, 
                method = "GCV.Cp",
                paraPen=list(cb_temps=penalized_mat))
  
  # summary(lag.gam)
  # AIC(lag.gam)
  
  #estimation of exposures effects
  
  #default plots
  pred_gam_Zs<-crosspred(cb_temps, lag.gam, 
                         cumul=F, cen=0, ci.level = 0.95,
                         at=seq(-4,4, 0.1))
  
  plot(pred_gam_Zs, "contour", main = lag_species, 
              xlab = "Temperature Deviation (°C)", 
              ylab = "Hours before collection")
  
  
  # 
  # plot(pred_gam_Zs, border = 2, cumul=F,
  #       theta=110,phi=20,ltheta=-80)
  
  # plot(pred_gam_Zs, "slices",
  #      var = c(3,-3),
  #      lag = c(1,200),
  #      col = 2)
  # 
}

Miscellany

run_starts = temp_record %>% 
  group_by(run) %>% 
  filter(minute_passed <= 3) %>% 
  summarise(start_temp = mean(temp_C)) %>% 
  mutate("temp_bin" = cut_number(start_temp, 4),
         temp_bin = case_when(
           temp_bin == "[2.7,9.26]" ~ "[2.7°C - 9.26°C]",
           temp_bin == "(9.26,13.9]" ~ "[9.26°C - 13.9°C]",
           temp_bin == "(13.9,21]" ~ "[13.9°C - 21°C]",
           temp_bin == "(21,30.5]" ~ "[21°C - 30.5°C]"
         ))

ramp_record2 = ramp_record %>% 
  group_by(run, minute_interval) %>% 
  summarise(mean_ramp = mean(ramp_per_minute)) %>% 
  ungroup() %>% 
  left_join(run_starts) %>% 
  mutate(temp_bin = fct_reorder(temp_bin, start_temp, .fun = mean))

ggplot(ramp_record2, aes(x = minute_interval, y = mean_ramp)) + 
  facet_wrap(temp_bin~.) + 
  geom_hline(yintercept = 0.3, colour = "grey") + 
  geom_hline(yintercept = 0.1, colour = "grey") + 
  geom_hex(aes(fill = cut(..count.., c(2, 5, 10, 20, 30, 40, 50))),
           bins = 30) + 
  scale_fill_viridis_d(name="Number of Observations",
                       labels = c("<5", "5-9", "10-19", "20-29", "30-39", "40-50"),
                       option = "mako") + 
  labs(y = "Ramp Rate (deg. C / min.)",
       x = "Time into run (minute)") + 
  theme_matt_facets(base_size = 12)


if(predict_vuln == F){

  knitr::knit_exit()

}
LS0tCnRpdGxlOiBTZWFzb25hbGl0eSBpbiBMYWtlIENoYW1wbGFpbiBDb3BlcG9kIFRoZXJtYWwgTGltaXRzCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgICAgICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICAgICAgICB0b2M6IHRydWUKICAgICAgICAgIHRvY19mbG9hdDogdHJ1ZQogIGdpdGh1Yl9kb2N1bWVudDoKICAgICAgICAgIGh0bWxfcHJldmlldzogZmFsc2UKICAgICAgICAgIHRvYzogdHJ1ZQogICAgICAgICAgdG9jX2RlcHRoOiAzCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9VCwgbWVzc2FnZSA9IEYsIHdhcm5pbmcgPSBGLCBlY2hvID0gRn0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBrbml0cjo6aXNfaHRtbF9vdXRwdXQoKSwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBmaWcucGF0aCA9ICIuLi9GaWd1cmVzL21hcmtkb3duLyIsCiAgZGV2ID0gYygicG5nIiwgInBkZiIpLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgY29sbGFwc2UgPSBUCikKCnRoZW1lX21hdHQgPSBmdW5jdGlvbihiYXNlX3NpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgIGRhcmtfdGV4dCA9ICJncmV5MjAiKXsKICBtaWRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzJdCiAgbGlnaHRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzNdCiAgCiAgZ2dwdWJyOjp0aGVtZV9wdWJyKGJhc2VfZmFtaWx5PSJzYW5zIikgJStyZXBsYWNlJSAKICAgIHRoZW1lKAogICAgICBwYW5lbC5iYWNrZ3JvdW5kICA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9ibGFuaygpLAogICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9IG1pZF90ZXh0LCBsaW5laGVpZ2h0ID0gMS4xKSwKICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gZGFya190ZXh0KSwKICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBtaWRfdGV4dCksCiAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDMsIDAsIDAsIDApLCAibW0iKSksCiAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDAsIDUsIDAsIDApLCAibW0iKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmdsZSA9IDkwKSwKICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT1iYXNlX3NpemUgKiAwLjkpLAogICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDAuOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlID0gImJvbGQiKSwKICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMC4yNSwgMC4yNSwgMC4yNSwgMC4yNSwiY20iKQogICAgKQp9Cgp0aGVtZV9tYXR0X2ZhY2V0cyA9IGZ1bmN0aW9uKGJhc2Vfc2l6ZSA9IDE4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhcmtfdGV4dCA9ICJncmV5MjAiKXsKICBtaWRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzJdCiAgbGlnaHRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzNdCiAgCiAgdGhlbWVfYncoYmFzZV9mYW1pbHk9InNhbnMiKSAlK3JlcGxhY2UlIAogICAgdGhlbWUoCiAgICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIHBhbmVsLmJhY2tncm91bmQgID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwgCiAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksCiAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9IG1pZF90ZXh0LCBsaW5laGVpZ2h0ID0gMS4xKSwKICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUpLAogICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS41LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBkYXJrX3RleHQpLAogICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IG1pZF90ZXh0KSwKICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSB1bml0KGMoMywgMCwgMCwgMCksICJtbSIpKSwKICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSB1bml0KGMoMCwgNSwgMCwgMCksICJtbSIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZ2xlID0gOTApLAogICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPWJhc2Vfc2l6ZSAqIDAuOSksCiAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMC45LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2UgPSAiYm9sZCIpLAogICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbigwLjI1LCAwLjI1LCAwLjI1LCAwLjI1LCJjbSIpCiAgICApCn0KCnNwZWNpZXNfY29scyA9IGMoIkxlcHRvZGlhcHRvbXVzIG1pbnV0dXMiID0gIiNmZmQwMjkiLAogICAgICAgICAgICAgICAgICJMZXB0b2RpYXB0b211cyBtaW51dHVzIGp1dmVuaWxlIiA9ICIjZTNkOGFmIiwKICAgICAgICAgICAgICAgICAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyBtYWxlIiA9ICIjZmZlODk2IiwKICAgICAgICAgICAgICAgICAiTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyIgPSAiI2YwOGY0NiIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMgbWFsZSIgPSAiI0UyOEMwMCIsCiAgICAgICAgICAgICAgICAgIlNraXN0b2RpYXB0b211cyBzcCIgPSAiI0M1QzM1QSIsCiAgICAgICAgICAgICAgICAgIlNraXN0b2RpYXB0b211cyBzcCBtYWxlIiA9ICIjZDlkODkzIiwgCiAgICAgICAgICAgICAgICAgIlNraXN0b2RpYXB0b211cyBzcCBqdXZlbmlsZSIgPSAiI2U2ZTZhYSIsIAogICAgICAgICAgICAgICAgICJFcGlzY2h1cmEgbGFjdXN0cmlzIGp1dmVuaWxlIiA9ICJwbHVtMSIsIAogICAgICAgICAgICAgICAgICJFcGlzY2h1cmEgbGFjdXN0cmlzIG1hbGUiID0gInBsdW0zIiwgCiAgICAgICAgICAgICAgICAgIkVwaXNjaHVyYSBsYWN1c3RyaXMiID0gInBsdW00IiwgCiAgICAgICAgICAgICAgICAgIkxpbW5vY2FsYW51cyBtYWNydXJ1cyIgPSAic2t5Ymx1ZTQiLCAKICAgICAgICAgICAgICAgICAiTGltbm9jYWxhbnVzIG1hY3J1cnVzIG1hbGUiID0gInNreWJsdWUzIiwgCiAgICAgICAgICAgICAgICAgIkxpbW5vY2FsYW51cyBtYWNydXJ1cyBqdXZlbmlsZSIgPSAic2t5Ymx1ZSIsIAogICAgICAgICAgICAgICAgICJTZW5lY2VsbGEgY2FsYW5vaWRlcyIgPSAiZGFya3NlYWdyZWVuMyIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZG9yYSBraW5kdGkgbWFsZSIgPSAibGlnaHRibHVlMyIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZG9yYSBraW5kdGkiID0gImxpZ2h0Ymx1ZTQiLAogICAgICAgICAgICAgICAgICJMZXB0b2RvcmEga2luZHRpIGp1dmVuaWxlIiA9ICJsaWdodGJsdWUiLAogICAgICAgICAgICAgICAgICJPc3BocmFudGljdW0gbGFicm9uZWN0dW0iID0gImZpcmVicmljazMiKQpgYGAKCiMjIENvcGVwb2QgQ29sbGVjdGlvbgoKQ29wZXBvZHMgd2VyZSBjb2xsZWN0ZWQgYXQgYXBwcm94aW1hdGVseSB3ZWVrbHkgaW50ZXJ2YWxzIGZyb20gTGFrZSBDaGFtcGxhaW4gKEJ1cmxpbmd0b24gRmlzaGluZyBQaWVyKS4gUGxhbmt0b24gd2FzIGNvbGxlY3RlZCBmcm9tIHRoZSB0b3AgMyBtZXRlcnMgdXNpbmcgYSAyNTAgdW0gbWVzaCBuZXQuIAoKYGBge3J9CiMgIyBMYWtlIENoYW1wbGFpbiBuZWFyIEJ1cmxpbmd0b24sIFZUCiMgc2l0ZU51bWJlciA9ICIwNDI5NDUwMCIKIyBDaGFtcGxhaW5JbmZvID0gcmVhZE5XSVNzaXRlKHNpdGVOdW1iZXIpCiMgcGFyYW1ldGVyQ2QgPSAiMDAwMTAiCiMgc3RhcnREYXRlID0gIjIwMjMtMDEtMDEiCiMgZW5kRGF0ZSA9ICIyMDI0LTUtMjAiCiMgI3N0YXRDZCA9IGMoIjAwMDAxIiwgIjAwMDAyIiwiMDAwMDMiLCAiMDAwMTEiKSAjIDEgLSBtYXgsIDIgLSBtaW4sIDMgPSBtZWFuCiMgCiMgIyBDb25zdHJ1Y3RzIHRoZSBVUkwgZm9yIHRoZSBkYXRhIHdhbnRlZCB0aGVuIGRvd25sb2FkcyB0aGUgZGF0YQojIHVybCA9IGNvbnN0cnVjdE5XSVNVUkwoc2l0ZU51bWJlcnMgPSBzaXRlTnVtYmVyLCBwYXJhbWV0ZXJDZCA9IHBhcmFtZXRlckNkLAojICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnREYXRlID0gc3RhcnREYXRlLCBlbmREYXRlID0gZW5kRGF0ZSwgc2VydmljZSA9ICJ1diIpCiMgCiMgcmF3X3RlbXBzID0gaW1wb3J0V2F0ZXJNTDEodXJsLCBhc0RhdGVUaW1lID0gVCkgJT4lCiMgICBtdXRhdGUoImRhdGUiID0gYXMuRGF0ZShkYXRlVGltZSksCiMgICAgICAgICAgImhvdXIiID0gaG91cihkYXRlVGltZSkpICU+JQojICAgc2VsZWN0KGRhdGVUaW1lLCB0el9jZCwgZGF0ZSwgaG91ciwgZGVnQyA9IFhfMDAwMTBfMDAwMDApCiMgCiMgdGVtcF9kYXRhID0gIHJhd190ZW1wcyAlPiUKIyAgIHNlbGVjdChkYXRlLCBob3VyLCAidGVtcCIgPSBkZWdDKQojIAojIHdyaXRlLmNzdih0ZW1wX2RhdGEsIGZpbGUgPSAiLi9PdXRwdXQvRGF0YS9jaGFtcGxhaW5fdGVtcHMuY3N2Iiwgcm93Lm5hbWVzID0gRikKYGBgCgpDb2xsZWN0aW9ucyBiZWdhbiBpbiBsYXRlIE1heSAyMDIzLiBTZXZlcmFsIGdhcHMgYXJlIHByZXNlbnQsIGJ1dCBjb2xsZWN0aW9ucyBoYXZlIGNvbnRpbnVlZCBhdCByb3VnaGx5IHdlZWtseSBpbnRlcnZhbHMgc2luY2UgdGhlbi4gQ29wZXBvZHMgZnJvbSBgciBsZW5ndGgodW5pcXVlKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX2RhdGUpKWAgY29sbGVjdGlvbnMgd2VyZSB1c2VkIHRvIG1ha2UgYSB0b3RhbCBvZiBgciBkaW0oZnVsbF9kYXRhKVsxXWAgdGhlcm1hbCBsaW1pdCBtZWFzdXJlbWVudHMuIE92ZXIgdGhpcyB0aW1lIHBlcmlvZCwgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZXMgcmFuZ2VkIGZyb20gYHIgcGFzdGUobWluKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX3RlbXApLCAiIHRvICIsIG1heChmdWxsX2RhdGEkY29sbGVjdGlvbl90ZW1wKSwgc2VwID0gIiIpYMKwQy4gICAgIAoKVGhlcmUgaXMgc3Vic3RhbnRpYWwgdmFyaWF0aW9uIGluIHRoZXJtYWwgbGltaXRzIGFjcm9zcyB0aGUgc3BlY2llcyBjb2xsZWN0ZWQuIFRoZXJlIGlzIGFsc28gc29tZSBkZWdyZWUgb2YgdmFyaWF0aW9uIHdpdGhpbiB0aGUgc3BlY2llcywgd2l0aCB0aGVybWFsIGxpbWl0cyBpbmNyZWFzaW5nIHNsaWdodGx5IGR1cmluZyB0aGUgc3VtbWVyLiAgICAKCmBgYHtyIG1haW4tZmlnLWN0bWF4LXRpbWVzZXJpZXMsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTV9CiMjIERhaWx5IHZhbHVlcyBmb3IgdGhlIHBlcmlvZCBleGFtaW5lZCBieSBkYXRhc2V0CmNvbGxlY3Rpb25fY29uZGl0aW9ucyA9IHRlbXBfZGF0YSAlPiUKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl90ZW1wID0gbWVhbih0ZW1wKSwKICAgICAgICAgICAgbWVkX3RlbXAgPSBtZWRpYW4odGVtcCksCiAgICAgICAgICAgIHZhcl90ZW1wID0gdmFyKHRlbXApLCAKICAgICAgICAgICAgbWluX3RlbXAgPSBtaW4odGVtcCksIAogICAgICAgICAgICBtYXhfdGVtcCA9IG1heCh0ZW1wKSkgJT4lIAogIG11dGF0ZSgicmFuZ2VfdGVtcCIgPSBtYXhfdGVtcCAtIG1pbl90ZW1wLAogICAgICAgICBkYXRlID0gYXMuRGF0ZShkYXRlKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgIAogIGZpbHRlcihkYXRlID49IChtaW4oYXMuRGF0ZShmdWxsX2RhdGEkY29sbGVjdGlvbl9kYXRlKSkgLSA3KSkgJT4lIAogIGxlZnRfam9pbih1bmlxdWUoc2VsZWN0KGZ1bGxfZGF0YSwgY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXApKSwgYnkgPSBqb2luX2J5KGRhdGUgPT0gY29sbGVjdGlvbl9kYXRlKSkKCiMjIE1lYW4gZmVtYWxlIHRoZXJtYWwgbGltaXRzIGZvciBlYWNoIHNwZWNpZXMsIGdyb3VwZWQgYnkgY29sbGVjdGlvbgpzcGVjaWVzX3N1bW1hcmllcyA9IGZ1bGxfZGF0YSAlPiUgIAogICNmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXApICU+JSAgCiAgc3VtbWFyaXNlKCJtZWFuX2N0bWF4IiA9IG1lYW4oY3RtYXgpLAogICAgICAgICAgICAic2FtcGxlX3NpemUiID0gbigpLAogICAgICAgICAgICAiY3RtYXhfc3RfZXJyIiA9IChzZChjdG1heCkgLyBzcXJ0KHNhbXBsZV9zaXplKSksCiAgICAgICAgICAgICJjdG1heF92YXIiID0gdmFyKGN0bWF4KSwgCiAgICAgICAgICAgICJtZWFuX3NpemUiID0gbWVhbihzaXplKSwKICAgICAgICAgICAgInNpemVfc3RfZXJyIiA9IChzZChzaXplKSAvIHNxcnQoc2FtcGxlX3NpemUpKSwKICAgICAgICAgICAgInNpemVfdmFyIiA9IHZhcihzaXplKSkgJT4lICAKICB1bmdyb3VwKCkgJT4lIAogIGNvbXBsZXRlKHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIGFycmFuZ2UoZGVzYyhzYW1wbGVfc2l6ZSkpCgphZHVsdF9zdW1tYXJpZXMgPSBmdWxsX2RhdGEgJT4lICAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXApICU+JSAgCiAgc3VtbWFyaXNlKCJtZWFuX2N0bWF4IiA9IG1lYW4oY3RtYXgpLAogICAgICAgICAgICAic2FtcGxlX3NpemUiID0gbigpLAogICAgICAgICAgICAiY3RtYXhfc3RfZXJyIiA9IChzZChjdG1heCkgLyBzcXJ0KHNhbXBsZV9zaXplKSksCiAgICAgICAgICAgICJjdG1heF92YXIiID0gdmFyKGN0bWF4KSwgCiAgICAgICAgICAgICJtZWFuX3NpemUiID0gbWVhbihzaXplKSwKICAgICAgICAgICAgInNpemVfc3RfZXJyIiA9IChzZChzaXplKSAvIHNxcnQoc2FtcGxlX3NpemUpKSwKICAgICAgICAgICAgInNpemVfdmFyIiA9IHZhcihzaXplKSkgJT4lICAKICB1bmdyb3VwKCkgJT4lIAogIGNvbXBsZXRlKHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIGFycmFuZ2UoZGVzYyhzYW1wbGVfc2l6ZSkpCgoKdHNlcmllc19kYXRhID0gZnVsbF9kYXRhICU+JSAKICBtdXRhdGUoc3BfbmFtZSA9IGZjdF9yZW9yZGVyKHNwX25hbWUsIGN0bWF4LCAuZGVzYyA9IFQpKQoKZ2dwbG90KCkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IGNvbGxlY3Rpb25fY29uZGl0aW9ucywgCiAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShkYXRlKSwgeSA9IG1lYW5fdGVtcCksCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIAogICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcih0c2VyaWVzX2RhdGEsIHNwZWNpZXMgIT0gIm9zcGhyYW50aWN1bV9sYWJyb25lY3R1bSIpLCAKICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpLAogICAgICAgICAgICAgc2l6ZSA9IDEuNSwgc2hhcGUgPSAxNiwgYWxwaGEgPSAwLjksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDAsIGhlaWdodCA9IDApKSArIAogICAgZ2VvbV9wb2ludChkYXRhID0gZmlsdGVyKHRzZXJpZXNfZGF0YSwgc3BlY2llcyA9PSAib3NwaHJhbnRpY3VtX2xhYnJvbmVjdHVtIiksIAogICAgICAgICAgICAgYWVzKHggPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBjdG1heCwgY29sb3VyID0gc3BfbmFtZSksCiAgICAgICAgICAgICBzaXplID0gMiwgc2hhcGUgPSAxNiwgYWxwaGEgPSAwLjksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDAsIGhlaWdodCA9IDApKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEsIHNpemUgPSA1KSkpICsgCiAgbGFicyh4ID0gIkRhdGUiLCAKICAgICAgIHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLCAKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIiwKICAgICAgIHNpemUgPSAiU2FtcGxlIFNpemUiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzIwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKCmxha2VfdGVtcHMgPSBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShkYXRhID0gY29sbGVjdGlvbl9jb25kaXRpb25zLCAKICAgICAgICAgICAgYWVzKHggPSBhcy5EYXRlKGRhdGUpLCB5ID0gbWVhbl90ZW1wKSwKICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIiwgCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEpICsgCiAgbGFicyh4ID0gIkRhdGUiLCAKICAgICAgIHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLCAKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIiwKICAgICAgIHNpemUgPSAiU2FtcGxlIFNpemUiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKVGVtcGVyYXR1cmVzIG9ic2VydmVkIGF0IHRoZSB0aW1lIG9mIGNvbGxlY3Rpb24gY2xvc2VseSByZXNlbWJsZWQgdGhlIG1heGltdW0gZGFpbHkgdGVtcGVyYXR1cmUgZnJvbSB0aGUgdGVtcGVyYXR1cmUgc2Vuc29yIGRhdGEuIE1heGltdW0gdGVtcGVyYXR1cmUgd2FzIHVzZWQgYXMgYSBwcm94eSBpbnN0ZWFkIG9mIG1lYW4gdGVtcGVyYXR1cmUgYXMgY29sbGVjdGlvbnMgd2VyZSB1c3VhbGx5IG1hZGUgZHVyaW5nIGFmdGVybm9vbnMgb3IgZWFybHkgZXZlbmluZ3MsIGp1c3QgZm9sbG93aW5nIHRoZSB3YXJtZXN0IHBhcnQgb2YgdGhlIGRheS4gCgpgYGB7ciBzdXBwLWZpZy10ZW1wLWFjYywgZmlnLndpZHRoID0gNiwgZmlnLmhlaWdodD02fQpjb2xsZWN0aW9uX2NvbmRpdGlvbnMgJT4lIAogIGRyb3BfbmEoY29sbGVjdGlvbl90ZW1wKSAlPiUgIAogIGdncGxvdChhZXMoeCA9IG1heF90ZW1wLCB5ID0gY29sbGVjdGlvbl90ZW1wKSkgKyAKICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEsCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMSwgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYyg1LDE1LDI1KSkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYyg1LDE1LDI1KSkgKyAKICBsYWJzKHggPSAiTWF4LiBUZW1wLiBmcm9tIFNlbnNvciAowrBDKSIsCiAgICAgICB5ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiKSArIAogIHRoZW1lX21hdHQoKQpgYGAKCmBgYHtyIG1pc2Mtcm91bmQtc3VtbWFyeS0yLCBmaWcud2lkdGg9MTEsIGZpZy5oZWlnaHQ9MTEsIGluY2x1ZGUgPSBGfQpnZ3Bsb3QoKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IAogICAgICAgICAgICAgICBjKG1heChmdWxsX2RhdGEkY29sbGVjdGlvbl90ZW1wKSwKICAgICAgICAgICAgICAgICBtaW4oZnVsbF9kYXRhJGNvbGxlY3Rpb25fdGVtcCkpLCAKICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5NjAiLAogICAgICAgICAgICAgbGluZXdpZHRoID0gYygyLDEpLCAKICAgICAgICAgICAgIGFscGhhID0gMC41KSArIAogIGdlb21fYmFyKGRhdGEgPSB1bmlxdWUoc2VsZWN0KGZ1bGxfZGF0YSwgY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXApKSwgCiAgICAgICAgICAgYWVzKHggPSBhc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBjb2xsZWN0aW9uX3RlbXApLAogICAgICAgICAgIHN0YXQgPSAiaWRlbnRpdHkiLAogICAgICAgICAgIGZpbGwgPSAiZ3JleTMwIikgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBmdWxsX2RhdGEsIAogICAgICAgICAgICAgYWVzKHggPSBhc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBjdG1heCksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDAuNywgaGVpZ2h0ID0gMCksCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTMwIiwKICAgICAgICAgICAgIGFscGhhID0gMC41KSArIAogIHlsaW0oLTMsIDQwKSArIAogIGNvb3JkX3BvbGFyKHN0YXJ0ID0gMCkgKyAKICB0aGVtZV92b2lkKCkKYGBgCgoKU2l6ZSBhbHNvIHZhcmllZCwgYnV0IHByaW1hcmlseSBiZXR3ZWVuIHJhdGhlciB0aGFuIHdpdGhpbiBzcGVjaWVzLiAKCmBgYHtyIHN1cHAtZmlnLXNpemUtdGltZXNlcmllcywgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTV9CmdncGxvdCgpICsgCiAgZ2VvbV92bGluZShkYXRhID0gdW5pcXVlKHNlbGVjdChmdWxsX2RhdGEsIGNvbGxlY3Rpb25fZGF0ZSkpLCAKICAgICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpKSwKICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5OTAiLAogICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IGNvbGxlY3Rpb25fY29uZGl0aW9ucywgCiAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShkYXRlKSwgeSA9IG1lYW5fdGVtcCksCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIAogICAgICAgICAgICBsaW5ld2lkdGggPSAyKSArIAogICMgZ2VvbV9lcnJvcmJhcihkYXRhID0gc3BlY2llc19zdW1tYXJpZXMsCiAgIyAgICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCAKICAjICAgICAgICAgICAgICAgICAgIHltaW4gPSBtZWFuX2N0bWF4IC0gY3RtYXhfc3RfZXJyLCB5bWF4ID0gbWVhbl9jdG1heCArIGN0bWF4X3N0X2VyciwKICAjICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IHNwX25hbWUpLAogICMgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMSksCiAgIyAgICAgICAgICAgICAgIHdpZHRoID0gNSwgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBhZHVsdF9zdW1tYXJpZXMsIAogICAgICAgICAgICAgYWVzKHggPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBtZWFuX3NpemUgKiA0MCwgY29sb3VyID0gc3BfbmFtZSwgc2l6ZSA9IHNhbXBsZV9zaXplKSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBuYW1lID0gIlRlbXBlcmF0dXJlIiwgIyBGZWF0dXJlcyBvZiB0aGUgZmlyc3QgYXhpcwogICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh+Li80MCwgbmFtZT0iUHJvc29tZSBMZW5ndGggKG1tKSIpLCAjIEFkZCBhIHNlY29uZCBheGlzIGFuZCBzcGVjaWZ5IGl0cyBmZWF0dXJlcwogICAgYnJlYWtzID0gYygwLDUsMTAsMTUsMjAsMjUsMzApCiAgKSArIAogIGxhYnMoeCA9ICJEYXRlIiwgCiAgICAgICB5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwgCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgpgYGB7ciBtaXNjLXRyYWl0LWRveS1mZWF0dXJlLCBmaWcud2lkdGggPSAxNCwgZmlnLmhlaWdodCA9IDcsIGluY2x1ZGUgPSBGfQojU2hvd24gYmVsb3cgaXMgQ1RtYXggYW5kIGJvZHkgc2l6ZSBmb3IgdGhlIHNwZWNpZXMgd2l0aCB0aGUgbW9zdCBkYXRhICgqU2tpc3RvZGlhcHRvbXVzKiwgKkwuIG1pbnV0dXMqLCAqTC4gc2ljaWxpcyosIGFuZCAqRXBpc2NodXJhKiksIHBsb3R0ZWQgYWdhaW5zdCB0aGUgZGF5IG9mIHRoZSB5ZWFyIGZvciBlYWNoIHNleC9zdGFnZSBzZXBhcmF0ZWx5LiAKCmN0bWF4X2ZlYXR1cmUgPSBmdWxsX2RhdGEgJT4lICAKICBtdXRhdGUoZG95ID0geWRheShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgZmlsdGVyKHNwX25hbWUgJWluJSBjKCJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMiLCAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyIsICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIiwgIkVwaXNjaHVyYSBsYWN1c3RyaXMiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF9ncmlkKHNwX25hbWV+c2V4KSArIAogIGdlb21fcG9pbnQoKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJEYXkgb2YgdGhlIFllYXIiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpzaXplX2ZlYXR1cmUgPSBmdWxsX2RhdGEgJT4lICAKICBtdXRhdGUoZG95ID0geWRheShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgZmlsdGVyKHNwX25hbWUgJWluJSBjKCJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMiLCAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyIsICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIiwgIkVwaXNjaHVyYSBsYWN1c3RyaXMiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IHNpemUsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X2dyaWQoc3BfbmFtZX5zZXgpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkRheSBvZiB0aGUgWWVhciIsIAogICAgICAgeSA9ICJTaXplIChtbSkiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpnZ2FycmFuZ2UoY3RtYXhfZmVhdHVyZSwgc2l6ZV9mZWF0dXJlLCBjb21tb24ubGVnZW5kID0gVCwgbGFiZWxzID0gIkFVVE8iLCBsZWdlbmQgPSAibm9uZSIpCmBgYAoKYGBge3Igc3Atb2NjdXJlbmNlcywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NX0Kc2FtcGxlX2RhdGVzX3Bsb3QgPSBmdWxsX2RhdGEgJT4lICAKICBmaWx0ZXIoc3BfbmFtZSAhPSAiT3NwaHJhbnRpY3VtIGxhYnJvbmVjdHVtIikgJT4lIAogIG11dGF0ZShzcF9uYW1lID0gYXMuZmFjdG9yKHNwX25hbWUpLAogICAgICAgICBzcF9uYW1lID0gZmN0X3Jlb3JkZXIoc3BfbmFtZSwgY3RtYXgpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gbHVicmlkYXRlOjphc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksIAogICAgICAgICAgICAgeSA9IHNwX25hbWUsIGZpbGwgPSBzcF9uYW1lKSkgKyAKICAjIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzX2RhdGUoCiAgIyAgIGMoIjIwMjMtMDUtMDEiLAogICMgICAgICIyMDIzLTA5LTAxIiwKICAjICAgICAiMjAyNC0wMS0wMSIsCiAgIyAgICAgIjIwMjQtMDUtMDEiKSksCiAgIyAgIGNvbG91ciA9ICJncmV5IiwKICAjICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX2RlbnNpdHlfcmlkZ2VzKGJhbmR3aWR0aCA9IDMwLAogICAgICAgICAgICAgICAgICAgICAgaml0dGVyZWRfcG9pbnRzID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICBwb2ludF9zaGFwZSA9IDIxLAogICAgICAgICAgICAgICAgICAgICAgcG9pbnRfc2l6ZSA9IDEsCiAgICAgICAgICAgICAgICAgICAgICBwb2ludF9jb2xvdXIgPSAiZ3JleTMwIiwKICAgICAgICAgICAgICAgICAgICAgIHBvaW50X2FscGhhID0gMC44LAogICAgICAgICAgICAgICAgICAgICAgYWxwaGEgPSAwLjgsCiAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3BvaW50c19qaXR0ZXIoCiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCA9IDAuMSwgd2lkdGggPSAwKSkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjMgbW9udGhzIiwKICAgICAgICAgICAgICAgZGF0ZV9sYWJlbHMgPSAiJWIiKSArIAogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gbHVicmlkYXRlOjphc19kYXRlKGMoIjIwMjMtMDYtMDgiLCAiMjAyNC0wNS0wOCIpKSkgKyAKICBsYWJzKHggPSAiRGF5IG9mIFllYXIiLCAKICAgICAgIHkgPSAiU3BlY2llcyIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgI3RoZW1lX3JpZGdlcyhncmlkID0gVCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQpgYGAKClRoZSBzYW1wbGVzIGNhcHR1cmVkIHRoZSBicm9hZCBzZWFzb25hbCBjaGFuZ2VzIGluIGNhbGFub2lkIGNvcGVwb2QgY29tbXVuaXR5IGNvbXBvc2l0aW9uIGluIHRoZSBsYWtlLiBXZSBub3RlLCBob3dldmVyLCB0aGF0IHJhcmUgc3BlY2llcyAoZS5nLiAqU2VuZWNlbGxhKiBhbmQgKkxpbW5vY2FsYW51cyopIHdlcmUgb2Z0ZW4gcHJlZmVyZW50aWFsbHkgc2FtcGxlZCwgc28gYXJlIG92ZXItcmVwcmVzZW50ZWQgaW4gdGhlIGRhdGEgc2V0LiAKCmBgYHtyIHN1cHAtZmlnLXNwLXByb3BzLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDUsIGluY2x1ZGUgPSBGfQphZHVsdF9zdW1tYXJpZXMgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgbXV0YXRlKGNvbGxlY3Rpb25fbnVtID0gYXMubnVtZXJpYyhmYWN0b3IoY29sbGVjdGlvbl9kYXRlKSkpICU+JSAKICBncm91cF9ieShjb2xsZWN0aW9uX2RhdGUpICU+JSAgCiAgYXJyYW5nZShjb2xsZWN0aW9uX2RhdGUpICU+JSAKICBzZWxlY3Qoc3BfbmFtZSwgY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX251bSwgc2FtcGxlX3NpemUpICU+JSAKICBtdXRhdGUoc2FtcGxlX3NpemUgPSByZXBsYWNlX25hKHNhbXBsZV9zaXplLCAwKSkgJT4lIAogIG11dGF0ZSh0b3RhbCA9IHN1bShzYW1wbGVfc2l6ZSksCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBzYW1wbGVfc2l6ZSAvIHRvdGFsLAogICAgICAgICBjb2xsZWN0aW9uX2RhdGUgPSBsdWJyaWRhdGU6OmFzX2RhdGUoY29sbGVjdGlvbl9kYXRlKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fZGF0ZSwgeSA9IHBlcmNlbnRhZ2UsIGZpbGwgPSBzcF9uYW1lKSkgKyAKICBnZW9tX2FyZWEoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLDEpKSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIERhdGUiLCAKICAgICAgIHkgPSAiUHJvcG9ydGlvbiIsIAogICAgICAgZmlsbCA9ICJTcGVjaWVzIikgKyAKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZSgpKQpgYGAKClRocm91Z2hvdXQgdGhlIHNlYXNvbiwgdGhlIHByZXZhbGVuY2Ugb2YgdmFyaW91cyB1bmlkZW50aWZpZWQgcGF0aG9nZW5zIGFsc28gdmFyaWVkLCB3aXRoIHZlcnkgbGl0dGxlIGluZmVjdGlvbiBvYnNlcnZlZCBkdXJpbmcgdGhlIFdpbnRlciBhbmQgU3ByaW5nLiAKCmBgYHtyIHN1cHAtZmlnLXBhdGhvZ2VuLXByb3BzLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQpwYXRob2dlbl9jb2xzID0gYygibm8iID0gImdyZXk5NSIsICJjbG91ZHkiID0gImhvbmV5ZGV3MyIsICJzcG90IiA9ICJhbnRpcXVld2hpdGUzIiwgIm90aGVyIiA9ICJ0b21hdG8zIikKCmZ1bGxfZGF0YSAlPiUgCiAgc2VsZWN0KGNvbGxlY3Rpb25fZGF0ZSwgZGV2X2VnZ3MsIHBhdGhvZ2VuLCBsaXBpZHMsIHNwX25hbWUsIHNleCkgJT4lIAogIGdyb3VwX2J5KCkgJT4lIAogIGZpbHRlcihzZXggIT0gImp1dmVuaWxlIikgJT4lIAogIGdyb3VwX2J5KGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIGNvdW50KHBhdGhvZ2VuKSAlPiUgCiAgZmlsdGVyKHBhdGhvZ2VuICE9ICJ1bmNlcnRhaW4iKSAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9ICJjb2xsZWN0aW9uX2RhdGUiLCAKICAgICAgICAgICAgICBuYW1lc19mcm9tID0gcGF0aG9nZW4sIAogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gbiwKICAgICAgICAgICAgICB2YWx1ZXNfZmlsbCA9IDApICU+JSAKICBtdXRhdGUodG90YWwgPSBzdW0obm8sIGNsb3VkeSwgc3BvdCwgb3RoZXIpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKG5vLCBjbG91ZHksIHNwb3QsIG90aGVyKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGF0aG9nZW4iLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImNvdW50IikgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gY291bnQvdG90YWwsCiAgICAgICAgIGNvbGxlY3Rpb25fZGF0ZSA9IGx1YnJpZGF0ZTo6YXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLAogICAgICAgICBwYXRob2dlbiA9IGZjdF9yZWxldmVsKHBhdGhvZ2VuLCAibm8iLCAiY2xvdWR5IiwgInNwb3QiLCAib3RoZXIiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fZGF0ZSwgeSA9IHBlcmNlbnQsIGZpbGwgPSBwYXRob2dlbikpICsgCiAgZ2VvbV9hcmVhKCkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBwYXRob2dlbl9jb2xzKSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsMSkpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gRGF0ZSIsIAogICAgICAgeSA9ICJQcm9wb3J0aW9uIiwgCiAgICAgICBmaWxsID0gIlBhdGhvZ2VuIikgKyAKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZSgpKQpgYGAKClRoZSB0cmFuc3BhcmVudCBib2RpZXMgb2YgdGhlc2UgY29wZXBvZHMgYWxzbyBhbGxvd2VkIHVzIHRvIGV4YW1pbmUgc2Vhc29uYWwgcGF0dGVybnMgaW4gbGlwaWQgcmVzZXJ2ZXMgYW5kIGluIHRoZSBwcm9kdWN0aW9uIG9mIGVnZ3MuIE1hdHVyaW5nIG9vY3l0ZXMgYXJlIHZpc2libGUgaW4gZmVtYWxlIGNvcGVwb2RzIGJlZm9yZSB0aGV5IGFyZSByZWxlYXNlZC4gVGhlcmUgd2FzIG5vIHN0cm9uZyBzZWFzb25hbCBjeWNsZSBpbiB0aGUgcHJvZHVjdGlvbiBvZiB0aGVzZSBlZ2dzIGluIGFueSBzcGVjaWVzLCBhbmQgaW5zdGVhZCwgZmVtYWxlcyB3ZXJlIHJlcHJvZHVjdGl2ZWx5IGFjdGl2ZSB0aHJvdWdob3V0IHRoZWlyIHJlc3BlY3RpdmUgc2Vhc29ucyBvZiBvY2N1cmVuY2UuIAoKYGBge3Igc3VwcC1maWctZGV2ZWdncy1wcm9wcywgZmlnLmhlaWdodCA9IDE1LCBmaWcud2lkdGggPSA4fQpkZXZfZWdnc19jb2xzID0gYygibm8iID0gImdyZXk5NSIsICJ5ZXMiID0gImxpZ2h0Ymx1ZTMiKQoKZnVsbF9kYXRhICU+JSAKICBzZWxlY3QoY29sbGVjdGlvbl9kYXRlLCBkZXZfZWdncywgcGF0aG9nZW4sIGxpcGlkcywgc3BfbmFtZSwgc2V4KSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lIAogIGZpbHRlcihzZXggIT0gImp1dmVuaWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIGNvdW50KGRldl9lZ2dzKSAlPiUgCiAgZmlsdGVyKGRldl9lZ2dzICE9ICJ1bmNlcnRhaW4iKSAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGMoImNvbGxlY3Rpb25fZGF0ZSIsICJzcF9uYW1lIiksIAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBkZXZfZWdncywgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBuLAogICAgICAgICAgICAgIHZhbHVlc19maWxsID0gMCkgJT4lIAogIG11dGF0ZSh0b3RhbCA9IHN1bShubywgeWVzKSkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYyhubywgeWVzKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiZGV2X2VnZ3MiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImNvdW50IikgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gY291bnQvdG90YWwsCiAgICAgICAgIGNvbGxlY3Rpb25fZGF0ZSA9IGx1YnJpZGF0ZTo6YXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLAogICAgICAgICBkZXZfZWdncyA9IGZjdF9yZWxldmVsKGRldl9lZ2dzLCAibm8iLCAieWVzIikpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGNvbXBsZXRlKGNvbGxlY3Rpb25fZGF0ZSwgbmVzdGluZyhzcF9uYW1lLCBkZXZfZWdncyksIGZpbGwgPSBsaXN0KHBlcmNlbnQgPSAxKSkgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gaWZfZWxzZShpcy5uYSh0b3RhbCkgJiBkZXZfZWdncyA9PSAieWVzIiwgMCwgcGVyY2VudCkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBjb2xsZWN0aW9uX2RhdGUsIHkgPSBwZXJjZW50LCBmaWxsID0gZGV2X2VnZ3MpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBuY29sID0gMSkgKyAKICBnZW9tX2FyZWEoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGRldl9lZ2dzX2NvbHMpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwxKSkgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBEYXRlIiwgCiAgICAgICB5ID0gIlByb3BvcnRpb24iLCAKICAgICAgIGZpbGwgPSAiRGV2ZWxvcGluZyBcbkVnZ3MiKSArIAogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMjApICsgCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKCkpCmBgYAoKVGhlIHByZXNlbmNlIG9mIGxpcGlkcyB2YXJpZWQgYWNyb3NzIHNwZWNpZXMsIHdpdGggb25seSAqTC4gbWludXR1cyosICpMLiBzaWNpbGlzKiwgYW5kICpMaW1ub2NhbGFudXMqIHJlZ3VsYXJseSBwb3NzZXNzaW5nIGxpcGlkIHN0b3Jlcy4gCgpgYGB7ciBzdXBwLWZpZy1saXBpZHMtcHJvcHMsIGZpZy5oZWlnaHQgPSAxNSwgZmlnLndpZHRoID0gOH0KbGlwaWRfY29scyA9IGMoIm5vIiA9ICJncmV5OTUiLCAieWVzIiA9ICJzaWVubmEyIikKCmZ1bGxfZGF0YSAlPiUgCiAgc2VsZWN0KGNvbGxlY3Rpb25fZGF0ZSwgZGV2X2VnZ3MsIHBhdGhvZ2VuLCBsaXBpZHMsIHNwX25hbWUsIHNleCkgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JSAKICBmaWx0ZXIoc2V4ICE9ICJqdXZlbmlsZSIpICU+JSAKICBncm91cF9ieShzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUpICU+JSAKICBjb3VudChsaXBpZHMpICU+JSAKICBmaWx0ZXIobGlwaWRzICE9ICJ1bmNlcnRhaW4iKSAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGMoImNvbGxlY3Rpb25fZGF0ZSIsICJzcF9uYW1lIiksIAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBsaXBpZHMsIAogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gbiwKICAgICAgICAgICAgICB2YWx1ZXNfZmlsbCA9IDApICU+JSAKICBtdXRhdGUodG90YWwgPSBzdW0obm8sIHllcykpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMobm8sIHllcyksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gImxpcGlkcyIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBjb3VudC90b3RhbCwKICAgICAgICAgY29sbGVjdGlvbl9kYXRlID0gbHVicmlkYXRlOjphc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksCiAgICAgICAgIGxpcGlkcyA9IGZjdF9yZWxldmVsKGxpcGlkcywgIm5vIiwgInllcyIpKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBjb21wbGV0ZShjb2xsZWN0aW9uX2RhdGUsIG5lc3Rpbmcoc3BfbmFtZSwgbGlwaWRzKSwgZmlsbCA9IGxpc3QocGVyY2VudCA9IDEpKSAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBpZl9lbHNlKGlzLm5hKHRvdGFsKSAmIGxpcGlkcyA9PSAieWVzIiwgMCwgcGVyY2VudCkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBjb2xsZWN0aW9uX2RhdGUsIHkgPSBwZXJjZW50LCBmaWxsID0gbGlwaWRzKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LiwgbmNvbCA9IDEpICsgCiAgZ2VvbV9hcmVhKCkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBsaXBpZF9jb2xzKSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsMSkpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gRGF0ZSIsIAogICAgICAgeSA9ICJQcm9wb3J0aW9uIiwgCiAgICAgICBmaWxsID0gIkxpcGlkc1xuUHJlc2VudCIpICsgCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAyMCkgKyAKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoKSkKYGBgCgoKIyMgVGVtcGVyYXR1cmUgVmFyaWFiaWxpdHkKTGFrZSBDaGFtcGxhaW4gaXMgaGlnaGx5IHNlYXNvbmFsLCB3aXRoIGJvdGggYXZlcmFnZSB0ZW1wZXJhdHVyZXMgYW5kIHRlbXBlcmF0dXJlIHZhcmlhYmlsaXR5IGNoYW5naW5nIHRocm91Z2hvdXQgdGhlIHllYXIuIFRoZXNlIHBhdHRlcm5zIGluIHRoZSBleHBlcmllbmNlZCB0aGVybWFsIGVudmlyb25tZW50IG1heSBkcml2ZSB0aGUgb2JzZXJ2ZWQgdmFyaWF0aW9uIGluIGNvcGVwb2QgdGhlcm1hbCBsaW1pdHMuIEhvd2V2ZXIsIHRoZSB0aW1lIHBlcmlvZCBhZmZlY3RpbmcgY29wZXBvZCB0aGVybWFsIGxpbWl0cyBpcyB1bmtub3duLiBEZXBlbmRpbmcgdGhlIG9uIHRoZSBkdXJhdGlvbiBvZiB0aW1lIGNvbnNpZGVyZWQsIHRoZXJlIGFyZSBsYXJnZSBjaGFuZ2VzIGluIHRoZSBleHBlcmllbmNlZCBlbnZpcm9ubWVudCwgaW4gcGFydGljdWxhciByZWdhcmRpbmcgdGhlIHRlbXBlcmF0dXJlIHJhbmdlIGFuZCB2YXJpYW5jZS4gQ29uc2lkZXIgZm9yIGV4YW1wbGUgdGhyZWUgdGltZSBwZXJpb2RzOiB0aGUgZGF5IG9mIGNvbGxlY3Rpb24sIG9uZSB3ZWVrIHByaW9yIHRvIGNvbGxlY3Rpb24sIGFuZCBmb3VyIHdlZWtzIHByaW9yIHRvIGNvbGxlY3Rpb24uIFdoaWxlIHRoZSBvdmVyYWxsIHBhdHRlcm4gaXMgc2ltaWxhciwgd2UgY2FuIHNlZSB0aGF0LCB1bnN1cnByaXNpbmdseSwgY29uc2lkZXJpbmcgbG9uZ2VyIHBlcmlvZHMgb2YgdGltZSByZXN1bHRzIGluIGxhcmdlciByYW5nZXMgYW5kIHNsaWdodGx5IGNoYW5nZXMgdGhlIHBhdHRlcm4gb2YgdmFyaWFuY2UgZXhwZXJpZW5jZWQuIAoKYGBge3IgZGFpbHktdGVtcC1kYXRhLCBpbmNsdWRlID0gRn0KIyMgRGFpbHkgdmFsdWVzCmRhaWx5X3RlbXBfZGF0YSA9IHRlbXBfZGF0YSAlPiUKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl90ZW1wID0gbWVhbih0ZW1wKSwKICAgICAgICAgICAgbWVkX3RlbXAgPSBtZWRpYW4odGVtcCksCiAgICAgICAgICAgIHZhcl90ZW1wID0gdmFyKHRlbXApLCAKICAgICAgICAgICAgbWluX3RlbXAgPSBtaW4odGVtcCksIAogICAgICAgICAgICBtYXhfdGVtcCA9IG1heCh0ZW1wKSkgJT4lIAogIG11dGF0ZSgicmFuZ2VfdGVtcCIgPSBtYXhfdGVtcCAtIG1pbl90ZW1wKQoKZGF5X3ByaW9yX3RlbXBfZGF0YSA9IHRlbXBfZGF0YSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fdGVtcCA9IG1lYW4odGVtcCksCiAgICAgICAgICAgIG1lZF90ZW1wID0gbWVkaWFuKHRlbXApLAogICAgICAgICAgICB2YXJfdGVtcCA9IHZhcih0ZW1wKSwgCiAgICAgICAgICAgIG1pbl90ZW1wID0gbWluKHRlbXApLCAKICAgICAgICAgICAgbWF4X3RlbXAgPSBtYXgodGVtcCkpICU+JSAKICBtdXRhdGUoZGF0ZSA9IGRhdGUgKyAxKSAlPiUgCiAgcmVuYW1lX3dpdGgoLmZuID0gfiBwYXN0ZTAoInByaW9yX2RheV8iLCAueCksIC5jb2xzID0gYygtZGF0ZSkpCgpkYWlseV9wbG90ID0gZGFpbHlfdGVtcF9kYXRhICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMoLWRhdGUpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZSwgeSA9IHRlbXAsIGNvbG91ciA9IHBhcmFtZXRlcikpICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAogICAgIm1lYW5fdGVtcCIgPSAib2xpdmVkcmFiMyIsCiAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiAgICAibWF4X3RlbXAiID0gInRvbWF0byIsICAKICAgICJtaW5fdGVtcCIgPSAiZG9kZ2VyYmx1ZSIsCiAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiAgICAidmFyX3RlbXAiID0gImRhcmtnb2xkZW5yb2QxIgogICkpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsgCiAgZ2d0aXRsZSgiRGFpbHkgVmFsdWVzIikgKyAKICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAogICAgICAgeCA9ICIiKSArIAogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQpgYGAKCmBgYHtyIHByZWRpY3RvcnMtZnVuY3Rpb259CiMjIERlZmluaW5nIHRoZSBmdW5jdGlvbiB0byBnZXQgcHJlZGljdG9yIHZhbHVlcyBmb3IgcGVyaW9kcyBvZiBkaWZmZXJlbnQgbGVuZ3RocwpnZXRfcHJlZGljdG9ycyA9IGZ1bmN0aW9uKGRhaWx5X3ZhbHVlcywgcmF3X3RlbXAsIG5fZGF5cyl7CiAgcHJlZml4ID0gc3RyX3JlcGxhY2VfYWxsKHhmdW46Om51bWJlcnNfdG9fd29yZHMobl9kYXlzKSwgcGF0dGVybiA9ICIgIiwgcmVwbGFjZW1lbnQgPSAiLSIpCiAgCiAgbWVhbl92YWx1ZXMgPSBkYWlseV92YWx1ZXMgJT4lIAogICAgdW5ncm91cCgpICU+JSAKICAgIG11dGF0ZShtZWFuX21heCA9IHNsaWRlX3ZlYygueCA9IG1heF90ZW1wLCAuZiA9IG1lYW4sIC5iZWZvcmUgPSBuX2RheXMsIC5jb21wbGV0ZSA9IFQpLAogICAgICAgICAgIG1lYW5fbWluID0gc2xpZGVfdmVjKC54ID0gbWluX3RlbXAsIC5mID0gbWVhbiwgLmJlZm9yZSA9IG5fZGF5cywgLmNvbXBsZXRlID0gVCksCiAgICAgICAgICAgbWVhbl9yYW5nZSA9IHNsaWRlX3ZlYygueCA9IHJhbmdlX3RlbXAsIC5mID0gbWVhbiwgLmJlZm9yZSA9IG5fZGF5cywgLmNvbXBsZXRlID0gVCkpICU+JSAKICAgIHNlbGVjdChkYXRlLCBtZWFuX21heCwgbWVhbl9taW4sIG1lYW5fcmFuZ2UpICU+JSAKICAgIHJlbmFtZV93aXRoKCB+IHBhc3RlKHByZWZpeCwgImRheSIsIC54LCBzZXAgPSAiXyIpLCAuY29scyA9IGMoLWRhdGUpKQogIAogIHBlcmlvZF92YWx1ZXMgPSByYXdfdGVtcCAlPiUgCiAgICBtdXRhdGUobWVhbiA9IHNsaWRlX2luZGV4X21lYW4odGVtcCwgaSA9IGRhdGUsIGJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFfcm0gPSBUKSwKICAgICAgICAgICBtYXggPSBzbGlkZV9pbmRleF9tYXgodGVtcCwgaSA9IGRhdGUsIGJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCksCiAgICAgICAgICAgbWluID0gc2xpZGVfaW5kZXhfbWluKHRlbXAsIGkgPSBkYXRlLCBiZWZvcmUgPSBkYXlzKG5fZGF5cyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCksCiAgICAgICAgICAgbWVkID0gc2xpZGVfaW5kZXhfZGJsKHRlbXAsIC5pID0gZGF0ZSwgLmJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCwgLmYgPSBtZWRpYW4pLAogICAgICAgICAgIHZhciA9IHNsaWRlX2luZGV4X2RibCh0ZW1wLCAuaSA9IGRhdGUsIC5iZWZvcmUgPSBkYXlzKG5fZGF5cyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZiA9IHZhciksCiAgICAgICAgICAgcmFuZ2UgPSBtYXggLSBtaW4pICU+JSAgCiAgICBzZWxlY3QoLXRlbXApICU+JSAgCiAgICBkaXN0aW5jdCgpICU+JSAKICAgIHJlbmFtZV93aXRoKCB+IHBhc3RlKHByZWZpeCwgImRheSIsIC54LCBzZXAgPSAiXyIpLCAuY29scyA9IGMoLWRhdGUpKSU+JSAKICAgIGlubmVyX2pvaW4obWVhbl92YWx1ZXMsIGJ5ID0gYygiZGF0ZSIpKSAlPiUgIAogICAgZHJvcF9uYSgpCiAgCiAgcmV0dXJuKHBlcmlvZF92YWx1ZXMpCn0KYGBgCgpgYGB7ciBtaXNjLXByZWRpY3RvcnMtYW5kLXBsb3RzLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NSwgaW5jbHVkZSA9IEZ9CiMgIyMgR2V0dGluZyBwcmVkaWN0b3IgdmFyaWFibGVzIGZvciBkaWZmZXJlbnQgcGVyaW9kcwojIAojICMjIyBTaG9ydCAodGhyZWUgZGF5cykKIyB0aHJlZV9kYXlfdGVtcHMgPSBnZXRfcHJlZGljdG9ycyhkYWlseV92YWx1ZXMgPSBkYWlseV90ZW1wX2RhdGEsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gdGVtcF9kYXRhLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSAzKQojIAojICMjIyBPTkUgV0VFSwp3ZWVrX3RlbXBzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gZGFpbHlfdGVtcF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X3RlbXAgPSB0ZW1wX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSA3KQoKd2Vla19wbG90ID0gd2Vla190ZW1wcyAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IGMoLWRhdGUpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidGVtcCIpICU+JQogIGZpbHRlcihwYXJhbWV0ZXIgJWluJSBjKCJzZXZlbl9kYXlfbWVhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNldmVuX2RheV9tZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzZXZlbl9kYXlfbWF4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAic2V2ZW5fZGF5X21pbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNldmVuX2RheV92YXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzZXZlbl9kYXlfcmFuZ2UiKSkgJT4lCiAgbXV0YXRlKHBhcmFtZXRlciA9IHBhc3RlKHdvcmQocGFyYW1ldGVyLCBzdGFydCA9IDMsIHNlcCA9IGZpeGVkKCJfIikpLCAiX3RlbXAiLCBzZXAgPSAiIikpICU+JQogIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wLCBjb2xvdXIgPSBwYXJhbWV0ZXIpKSArCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiAgICAibWVhbl90ZW1wIiA9ICJvbGl2ZWRyYWIzIiwKICAgICJtZWRfdGVtcCIgPSAic2VhZ3JlZW4zIiwKICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwKICAgICJtaW5fdGVtcCIgPSAiZG9kZ2VyYmx1ZSIsCiAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiAgICAidmFyX3RlbXAiID0gImRhcmtnb2xkZW5yb2QxIgogICkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYXMuRGF0ZShjKCIyMDIzLTAxLTAxIiwgIjIwMjMtMDQtMDEiLCAiMjAyMy0wNy0wMSIpKSkgKwogIGdndGl0bGUoIk9uZSBXZWVrIikgKwogIGxhYnMoeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsCiAgICAgICB4ID0gIiIpICsKICB0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkgKwogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQojIAojIAojICMjIyBUV08gV0VFS1MKIyB0d29fd2Vla190ZW1wcyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGRhaWx5X3RlbXBfZGF0YSwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IHRlbXBfZGF0YSwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSAxNCkKIyAKIyB0d29fd2Vla19wbG90ID0gdHdvX3dlZWtfdGVtcHMgJT4lIAojICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKIyAgICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKIyAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidGVtcCIpICU+JSAKIyAgIGZpbHRlcihwYXJhbWV0ZXIgJWluJSBjKCJmb3VydGVlbl9kYXlfbWVhbiIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm91cnRlZW5fZGF5X21lZCIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm91cnRlZW5fZGF5X21heCIsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvdXJ0ZWVuX2RheV9taW4iLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3VydGVlbl9kYXlfdmFyIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3VydGVlbl9kYXlfcmFuZ2UiKSkgJT4lIAojICAgbXV0YXRlKHBhcmFtZXRlciA9IHBhc3RlKHdvcmQocGFyYW1ldGVyLCBzdGFydCA9IDMsIHNlcCA9IGZpeGVkKCJfIikpLCAiX3RlbXAiLCBzZXAgPSAiIikpICU+JSAKIyAgIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wLCBjb2xvdXIgPSBwYXJhbWV0ZXIpKSArIAojICAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiMgICAgICJtZWFuX3RlbXAiID0gIm9saXZlZHJhYjMiLAojICAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiMgICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwgIAojICAgICAibWluX3RlbXAiID0gImRvZGdlcmJsdWUiLAojICAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiMgICAgICJ2YXJfdGVtcCIgPSAiZGFya2dvbGRlbnJvZDEiCiMgICApKSArIAojICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsgCiMgICBnZ3RpdGxlKCJUd28gV2Vla3MiKSArIAojICAgbGFicyh5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwKIyAgICAgICAgeCA9ICIiKSArIAojICAgdGhlbWVfYncoYmFzZV9zaXplID0gMjApICsgCiMgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQojIAojIAojICMjIyBGT1VSIFdFRUtTCmZvdXJfd2Vla190ZW1wcyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGRhaWx5X3RlbXBfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X3RlbXAgPSB0ZW1wX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fZGF5cyA9IDI4KQoKZm91cl93ZWVrX3Bsb3QgPSBmb3VyX3dlZWtfdGVtcHMgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUKICBmaWx0ZXIocGFyYW1ldGVyICVpbiUgYygidHdlbnR5LWVpZ2h0X2RheV9tZWFuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAidHdlbnR5LWVpZ2h0X2RheV9tZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ0d2VudHktZWlnaHRfZGF5X21heCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInR3ZW50eS1laWdodF9kYXlfbWluIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAidHdlbnR5LWVpZ2h0X2RheV92YXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ0d2VudHktZWlnaHRfZGF5X3JhbmdlIikpICU+JQogIG11dGF0ZShwYXJhbWV0ZXIgPSBwYXN0ZSh3b3JkKHBhcmFtZXRlciwgc3RhcnQgPSAzLCBzZXAgPSBmaXhlZCgiXyIpKSwgIl90ZW1wIiwgc2VwID0gIiIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKwogIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAogICAgIm1lYW5fdGVtcCIgPSAib2xpdmVkcmFiMyIsCiAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiAgICAibWF4X3RlbXAiID0gInRvbWF0byIsCiAgICAibWluX3RlbXAiID0gImRvZGdlcmJsdWUiLAogICAgInJhbmdlX3RlbXAiID0gImdvbGRlbnJvZDMiLAogICAgInZhcl90ZW1wIiA9ICJkYXJrZ29sZGVucm9kMSIKICApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsKICBnZ3RpdGxlKCJGb3VyIFdlZWtzIikgKwogIGxhYnMoeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsCiAgICAgICB4ID0gIiIpICsKICB0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkgKwogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQojIAojIAojICMjIyBFSUdIVCBXRUVLUwojIGVpZ2h0X3dlZWtfdGVtcHMgPSBnZXRfcHJlZGljdG9ycyhkYWlseV92YWx1ZXMgPSBkYWlseV90ZW1wX2RhdGEsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IHRlbXBfZGF0YSwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fZGF5cyA9IDU2KQojIAojIGVpZ2h0X3dlZWtfcGxvdCA9IGVpZ2h0X3dlZWtfdGVtcHMgJT4lIAojICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKIyAgICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKIyAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidGVtcCIpICU+JSAKIyAgIGZpbHRlcihwYXJhbWV0ZXIgJWluJSBjKCJmaWZ0eS1zaXhfZGF5X21lYW4iLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfbWVkIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaWZ0eS1zaXhfZGF5X21heCIsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfbWluIiwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlmdHktc2l4X2RheV92YXIiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfcmFuZ2UiKSkgJT4lIAojICAgbXV0YXRlKHBhcmFtZXRlciA9IHBhc3RlKHdvcmQocGFyYW1ldGVyLCBzdGFydCA9IDMsIHNlcCA9IGZpeGVkKCJfIikpLCAiX3RlbXAiLCBzZXAgPSAiIikpICU+JSAKIyAgIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wLCBjb2xvdXIgPSBwYXJhbWV0ZXIpKSArIAojICAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiMgICAgICJtZWFuX3RlbXAiID0gIm9saXZlZHJhYjMiLAojICAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiMgICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwgIAojICAgICAibWluX3RlbXAiID0gImRvZGdlcmJsdWUiLAojICAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiMgICAgICJ2YXJfdGVtcCIgPSAiZGFya2dvbGRlbnJvZDEiCiMgICApKSArIAojICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsgCiMgICBnZ3RpdGxlKCJFaWdodCBXZWVrcyIpICsgCiMgICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAojICAgICAgICB4ID0gIiIpICsgCiMgICB0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkgKyAKIyAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiMgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDI3MCwgaGp1c3QgPSAwLCB2anVzdCA9IDAuNSkpCiMgCmdnYXJyYW5nZShkYWlseV9wbG90LCB3ZWVrX3Bsb3QsIGZvdXJfd2Vla19wbG90LCAKICAgICAgICAgIGNvbW1vbi5sZWdlbmQgPSBULCBucm93ID0gMSwgbGFiZWxzID0gIkFVVE8iLCBsZWdlbmQgPSAiYm90dG9tIikKYGBgCgpgYGB7ciBtaXNjLWNvcnItcGVyaW9kcywgaW5jbHVkZSA9IEZ9CiNUaGUgZGlmZmVyZW50IHRpbWUgcGVyaW9kcyBleGFtaW5lZCBieSB0aGlzIGNsaW1hdGUgZGF0YSBoaWdobGlnaHRzIHRoYXQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1pbmltdW0gYW5kIG1heGltdW0gdGVtcGVyYXR1cmVzIGNoYW5nZXMgYmFzZWQgb24gdGhlIHdpbmRvdyBleGFtaW5lZC4gRm9yIGV4YW1wbGUsIG1pbmltdW0gYW5kIG1heGltdW0gdGVtcGVyYXR1cmVzIGV4cGVyaWVuY2VkIG92ZXIgd2Vla2x5IGludGVydmFscyBhcmUgY2xvc2VseSBsaW5rZWQsIHdoZXJlYXMgdGhlcmUgaXMgYSBkaXN0aW5jdCBzZWFzb25hbCBjeWNsZSBpbiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gbWluaW11bSBhbmQgbWF4aW11bSB0ZW1wZXJhdHVyZXMgZXhwZXJpZW5jZWQgb3ZlciBwZXJpb2RzIG9mIGZvdXIgd2Vla3MuIAoKb25lX3dlZWtfZG95X2RhdGEgPSB3ZWVrX3RlbXBzICU+JSAKICBtdXRhdGUoZG95ID0geWRheShkYXRlKSkKCm9uZV93ZWVrX3RlbXBfY2lyY2xlID0gZ2dwbG90KG9uZV93ZWVrX2RveV9kYXRhLCBhZXMoeCA9IHNldmVuX2RheV9tZWFuX21heCwgeSA9IHNldmVuX2RheV9tZWFuX21pbiwgY29sb3VyID0gZG95KSkgKyAKICBnZW9tX3BvaW50KCkgKyAKICBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKAogICAgaGlnaCA9ICJkb2RnZXJibHVlNCIsCiAgICBtaWQgPSAiY29yYWwyIiwKICAgIGxvdyA9ICJkb2RnZXJibHVlNCIsCiAgICBtaWRwb2ludCA9IDE4Mi41KSArIAogIGxhYnMoeCA9ICJNYXguIFRlbXAuICjCsEMpIiwKICAgICAgIHkgPSAiTWluLiBUZW1wLiAowrBDKSIpICsgCiAgbGFicyh4ID0gIk1heC4gVGVtcC4gKMKwQykiLAogICAgICAgeSA9ICJNaW4uIFRlbXAuICjCsEMpIikgKyAKICBnZ3RpdGxlKCJPbmUgV2VlayIpICsgCiAgdGhlbWVfbWF0dCgpCgpmb3VyX3dlZWtfZG95X2RhdGEgPSBmb3VyX3dlZWtfdGVtcHMgJT4lIAogIG11dGF0ZShkb3kgPSB5ZGF5KGRhdGUpKQoKZm91cl93ZWVrX3RlbXBfY2lyY2xlID0gZ2dwbG90KGZvdXJfd2Vla19kb3lfZGF0YSwgYWVzKHggPSBgdHdlbnR5LWVpZ2h0X2RheV9tYXhgLCB5ID0gYHR3ZW50eS1laWdodF9kYXlfbWluYCwgY29sb3VyID0gZG95KSkgKyAKICBnZW9tX3BvaW50KCkgKyAKICBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKAogICAgaGlnaCA9ICJkb2RnZXJibHVlNCIsCiAgICBtaWQgPSAiY29yYWwyIiwKICAgIGxvdyA9ICJkb2RnZXJibHVlNCIsCiAgICBtaWRwb2ludCA9IDE4Mi41KSArIAogIGxhYnMoeCA9ICJNYXguIFRlbXAuICjCsEMpIiwKICAgICAgIHkgPSAiTWluLiBUZW1wLiAowrBDKSIpICsgCiAgZ2d0aXRsZSgiRm91ciBXZWVrIikgKyAKICB0aGVtZV9tYXR0KCkKCmdnYXJyYW5nZShvbmVfd2Vla190ZW1wX2NpcmNsZSwgZm91cl93ZWVrX3RlbXBfY2lyY2xlLAogICAgICAgICAgY29tbW9uLmxlZ2VuZCA9IFQsIGxhYmVscyA9ICJBVVRPIiwgbGVnZW5kID0gImJvdHRvbSIpCmBgYAoKT3JnYW5pc21zIGFyZSB1bmxpa2VseSB0byBhY2NsaW1hdGUgaW5zdGFudGFuZW91c2x5IHRvIGNoYW5nZXMgaW4gdGVtcGVyYXR1cmUuIFRvIGV4cGxvcmUgdGhlIHBvdGVudGlhbCB0ZW1wb3JhbCB3aW5kb3cgdGhlc2UgY29wZXBvZHMgYXJlIHJlc3BvbmRpbmcgdG8sIHdlIGV4YW1pbmVkIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZXJtYWwgbGltaXRzIGFuZCBzdW1tYXJpZXMgb2YgdGhlIHRoZXJtYWwgZW52aXJvbm1lbnQgb3ZlciBkaWZmZXJlbnQgcGVyaW9kcyBvZiB0aW1lLiBGb3IgZWFjaCBzcGVjaWVzIChpbmNsdXNpdmUgb2YgYWxsIHNleGVzIGFuZCBzdGFnZXMpLCB3ZSBleGFtaW5lZCB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiBDVG1heCBhbmQgb25lIG9mIG5pbmUgcmVwcmVzZW50YXRpb25zIG9mIHRoZSB0aGVybWFsIGVudmlyb25tZW50IGNhbGN1bGF0ZWQgZm9yIHBlcmlvZHMgb2YgdGltZSBmcm9tIDEgdG8gNjAgZGF5cyBiZWZvcmUgY29sbGVjdGlvbi4gVGhlc2UgcGFyYW1ldGVycyBpbmNsdWRlIHRoZSBvdmVyYWxsIG1heGltdW0sIG1pbmltdW0sIG1lZGlhbiwgYW5kIG1lYW4gdGVtcGVyYXR1cmUgZm9yIHRoZSBwZXJpb2Qgb2YgdGltZSwgdGhlIHRlbXBlcmF0dXJlIHJhbmdlIGFuZCB2YXJpYW5jZSBkdXJpbmcgdGhpcyB0aW1lLCBhbmQgdGhlIG1lYW4gZGFpbHkgdGVtcGVyYXR1cmUgbWF4aW11bSwgbWluaW11bSwgYW5kIHJhbmdlLiBXZSBhbHNvIGV4YW1pbmVkIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIENUbWF4IGFuZCB0aGUgdGVtcGVyYXR1cmUgcmVjb3JkZWQgYXQgdGhlIHRpbWUgb2YgY29sbGVjdGlvbi4gCgpgYGB7ciBlc3RpbWF0aW5nLXByZWRpY3Rvci1jb3JyZWxhdGlvbnMsIGluY2x1ZGUgPSBGfQojV2UgY2FuIHNlZSB0aGF0LCBpbiBnZW5lcmFsLCBjb3BlcG9kcyBhcmUgcmVzcG9uZGluZyB0byBwcm94aW1hdGUgY3VlcyBmcm9tIHRoZSB0aGVybWFsIGVudmlyb25tZW50LCB3aXRoIGNvcnJlbGF0aW9ucyBnZW5lcmFsbHkgZHJvcHBpbmcgb2ZmIHN1YnN0YW50aWFsbHkgYXMgYWNjbGltYXRpb24gd2luZG93IGR1cmF0aW9uIGluY3JlYXNlcy4gQW4gZXhjZXB0aW9uIGlzICpFcGlzY2h1cmEgbGFjdXN0cmlzKiwgd2hpY2ggYXBwZWFycyB0byBiZSByZXNwb25kaW5nIHRvIG1heGltdW0gdGVtcGVyYXR1cmVzIGV4cGVyaWVuY2VkIG92ZXIgYSAyMCBkYXkgdGltZSBwZXJpb2QuIAoKIyMjIFB1bGxpbmcgcHJlZGljdG9ycyBhbmQgbWVhc3VyaW5nIGNvcnJlbGF0aW9ucyBmb3IgbXVjaCBmaW5lciB0aW1lc2NhbGVzOyAxLTU2IGRheXMKCm51bV9jb2xscyA9IGZ1bGxfZGF0YSAlPiUgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIHNlbGVjdChjb2xsZWN0aW9uX2RhdGUsIHNwX25hbWUpICU+JSAgCiAgZGlzdGluY3QoKSAlPiUgIAogIGNvdW50KHNwX25hbWUpICU+JSAKICBmaWx0ZXIobiA+PSA1KQoKY29ycl92YWxzID0gZGF0YS5mcmFtZSgpCgpkdXJfdmFscyA9IGMoMTo1MCkKZm9yKGkgaW4gZHVyX3ZhbHMpewogIAogIGR1cmF0aW9uX3RlbXBzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gZGFpbHlfdGVtcF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gc2VsZWN0KHRlbXBfZGF0YSwgLWhvdXIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fZGF5cyA9IGkpICU+JSAKICAgIGZpbHRlcihkYXRlICVpbiUgYXNfZGF0ZSh1bmlxdWUoZnVsbF9kYXRhJGNvbGxlY3Rpb25fZGF0ZSkpKQogIAogIGNvcnJfZGF0YSA9IGZ1bGxfZGF0YSAlPiUKICAgIHNlbGVjdChzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUsIGNvbGxlY3Rpb25fdGVtcCwgc2V4LCBjdG1heCkgJT4lIAogICAgZmlsdGVyKHNwX25hbWUgJWluJSBudW1fY29sbHMkc3BfbmFtZSkgJT4lIAogICAgI2ZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICAgIG11dGF0ZShjb2xsZWN0aW9uX2RhdGUgPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSkpICU+JSAKICAgIGlubmVyX2pvaW4oZHVyYXRpb25fdGVtcHMsIGpvaW5fYnkoY29sbGVjdGlvbl9kYXRlID09IGRhdGUpKSAlPiUgCiAgICBwaXZvdF9sb25nZXIoY29scyA9IGMoY29sbGVjdGlvbl90ZW1wLCBjb250YWlucygiZGF5XyIpKSwKICAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsdWUiLCAKICAgICAgICAgICAgICAgICBuYW1lc190byA9ICJwcmVkaWN0b3IiKSAlPiUgIAogICAgZ3JvdXBfYnkoc3BfbmFtZSwgcHJlZGljdG9yKSAlPiUgCiAgICBzdW1tYXJpc2UoY29ycmVsYXRpb24gPSBjb3IudGVzdChjdG1heCwgdmFsdWUpJGVzdGltYXRlLAogICAgICAgICAgICAgIHAudmFsdWUgPSBjb3IudGVzdChjdG1heCwgdmFsdWUpJHAudmFsdWUsCiAgICAgICAgICAgICAgY2lfbG93ID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRjb25mLmludFsxXSwKICAgICAgICAgICAgICBjaV9oaWdoID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRjb25mLmludFsyXSwKICAgICAgICAgICAgICAuZ3JvdXBzID0gImtlZXAiKSAlPiUgCiAgICBmaWx0ZXIocHJlZGljdG9yICE9ICJjb2xsZWN0aW9uX3RlbXAiKSAlPiUgCiAgICBtdXRhdGUoc2lnID0gaWZlbHNlKHAudmFsdWUgPDAuMDUsICJTaWcuIiwgIk5vbiBTaWcuIikpICU+JSAKICAgIHNlcGFyYXRlKHByZWRpY3RvciwgIl9kYXlfIiwgaW50byA9IGMoTkEsICJwYXJhbWV0ZXIiKSkgJT4lIAogICAgbXV0YXRlKGR1cmF0aW9uID0gaSkKICAKICBjb3JyX3ZhbHMgPSBiaW5kX3Jvd3MoY29ycl92YWxzLCBjb3JyX2RhdGEpCn0KCmNvbGxfY29yciA9IGZ1bGxfZGF0YSAlPiUKICBmaWx0ZXIoc3BfbmFtZSAlaW4lIG51bV9jb2xscyRzcF9uYW1lKSAlPiUgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JSAKICBzdW1tYXJpc2UoY29ycmVsYXRpb24gPSBjb3IudGVzdChjdG1heCwgY29sbGVjdGlvbl90ZW1wKSRlc3RpbWF0ZSwKICAgICAgICAgICAgcC52YWx1ZSA9IGNvci50ZXN0KGN0bWF4LCBjb2xsZWN0aW9uX3RlbXApJHAudmFsdWUsCiAgICAgICAgICAgIGNpX2xvdyA9IGNvci50ZXN0KGN0bWF4LCBjb2xsZWN0aW9uX3RlbXApJGNvbmYuaW50WzFdLAogICAgICAgICAgICBjaV9oaWdoID0gY29yLnRlc3QoY3RtYXgsIGNvbGxlY3Rpb25fdGVtcCkkY29uZi5pbnRbMl0pICU+JSAKICBtdXRhdGUoc2lnID0gaWZlbHNlKHAudmFsdWUgPDAuMDUsICJTaWcuIiwgIk5vbiBTaWcuIikpICU+JSAKICBtdXRhdGUoZHVyYXRpb24gPSAwLAogICAgICAgICBwYXJhbWV0ZXIgPSAiY29sbF90ZW1wIikKCmNvcnJfdmFscyA9IGNvcnJfdmFscyAlPiUgIAogIG11dGF0ZShkdXJhdGlvbiA9IGFzLm51bWVyaWMoZHVyYXRpb24pKSAlPiUgCiAgYmluZF9yb3dzKGNvbGxfY29ycikKCmBgYAoKU2hvd24gYmVsb3cgYXJlIHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgZm9yIHRoZXNlIHJlbGF0aW9uc2hpcHMuIEVhY2ggZmFjZXQgc2hvd3MgdGhlIHJlbGF0aW9uc2hpcCBmb3IgYSBkaWZmZXJlbnQgcGFyYW1ldGVyLCBwbG90dGVkIGFnYWluc3QgdGhlIGR1cmF0aW9uIG9mIHRoZSB0aW1lIHBlcmlvZCBiZWZvcmUgY29sbGVjdGlvbi4gCgpgYGB7ciBzdXBwLWZpZy1jb3JyZWxhdGlvbi1kdXJhdGlvbnMsIGZpZy53aWR0aD0xNCwgZmlnLmhlaWdodD04LCBpbmNsdWRlID0gVH0KY29ycl92YWxzICU+JSAKICBtdXRhdGUocGFyYW1ldGVyID0gZmN0X3JlbGV2ZWwocGFyYW1ldGVyLCBjKCJtaW4iLCAibWF4IiwgInJhbmdlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtZWFuIiwgIm1lZCIsICJ2YXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1lYW5fbWluIiwgIm1lYW5fbWF4IiwgIm1lYW5fcmFuZ2UiKSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBkdXJhdGlvbiwgeSA9IGNvcnJlbGF0aW9uLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKC5+cGFyYW1ldGVyKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9wb2ludChzaXplID0gMC45KSArIAogIGdlb21fbGluZShsaW5ld2lkdGggPSAxLjUpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkR1cmF0aW9uIChkYXlzKSIsCiAgICAgICB5ID0gIkNvcnJlbGF0aW9uIiwgCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKQpgYGAKClRoaXMgdGFibGUgY29udGFpbnMgdGhlIHRvcCB0aHJlZSBmYWN0b3JzIGZvciBlYWNoIHNwZWNpZXMgKGJhc2VkIG9uIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50KS4KCmBgYHtyIHByZWRpY3Rvci1jb3JyZWxhdGlvbnMsIGluY2x1ZGUgPSBGfQpjb3JyX3ZhbHMgJT4lICAKICBmaWx0ZXIoc2lnID09ICJTaWcuIikgJT4lIAogIGRyb3BfbmEoY29ycmVsYXRpb24pICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUKICBhcnJhbmdlKGRlc2MoY29ycmVsYXRpb24pKSAlPiUgCiAgc2xpY2VfaGVhZChuID0gMykgJT4lIAogIHNlbGVjdCgiU3BlY2llcyIgPSBzcF9uYW1lLCAiUHJlZGljdG9yIiA9IHBhcmFtZXRlciwgIkR1cmF0aW9uIiA9IGR1cmF0aW9uLCAiQ29ycmVsYXRpb24iID0gY29ycmVsYXRpb24sICJQLVZhbHVlIiA9IHAudmFsdWUpICU+JSAKICBrbml0cjo6a2FibGUoYWxpZ24gPSAiYyIpCmBgYAoKU2hvd24gaGVyZSBpcyBhIGdyYXBoaWNhbCBzdW1tYXJ5IG9mIHRoZSBkdXJhdGlvbiBvZiB0aGUgYmVzdCBwcmVkaWN0b3JzIGZvciBlYWNoIHNwZWNpZXMuIE5vdGUgdGhhdCBmb3IgdGhlIHR3byBMZXB0b2RpYXB0b21pZHMsIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUgaGFkIHRoZSBsYXJnZXN0IGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IHNvIGR1cmF0aW9uIGlzIHplcm8uIFRoaXMgcmVwcmVzZW50YXRpb24gaGlnaGxpZ2h0cyB0aGF0IHRoZXJlIGlzIHZhcmlhdGlvbiBhY3Jvc3MgdGhlIGNvbW11bml0eSBub3Qgb25seSBpbiB0aGUgcG90ZW50aWFsIGRyaXZlciAoZS5nLiBtaW5pbXVtIHZzLiBtYXhpbXVtIHRlbXBlcmF0dXJlcykgYnV0IGFsc28gaW4gdGhlIGR1cmF0aW9uIG9mIHRpbWUuIFRoaXMgdmFyaWF0aW9uIGlzIG5vdCBncm91cGVkIGJ5IHNlYXNvbiAodGhlIHdpbnRlciBhbmQgc3VtbWVyIGNvbW11bml0aWVzIGJvdGggaGF2ZSByZXByZXNlbnRhdGl2ZSBzcGVjaWVzIGFwcGFyZW50bHkgcmVzcG9uZGluZyB0byBzaG9ydCBhbmQgbG9uZyBkdXJhdGlvbnMpLiAKCmBgYHtyIG1haW4tZmlnLWFjYy1kdXJhdGlvbnN9CmR1cmF0aW9uX3Bsb3QgPSBjb3JyX3ZhbHMgJT4lICAKICBmaWx0ZXIoc2lnID09ICJTaWcuIikgJT4lIAogIGRyb3BfbmEoY29ycmVsYXRpb24pICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUKICBhcnJhbmdlKGRlc2MoY29ycmVsYXRpb24pKSAlPiUgCiAgc2xpY2VfaGVhZChuID0gMSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgbXV0YXRlKCJudW0iID0gcm93X251bWJlcigpLCAKICAgICAgICAgc3BfbmFtZSA9IGZjdF9yZW9yZGVyKHNwX25hbWUsIGR1cmF0aW9uLCAuZnVuID0gbWVhbiwgLmRlc2MgPSBUKSkgJT4lIAogIGFycmFuZ2Uoc3BfbmFtZSkgJT4lIAogIHNlbGVjdCgiU3BlY2llcyIgPSBzcF9uYW1lLCAiUHJlZGljdG9yIiA9IHBhcmFtZXRlciwgIkR1cmF0aW9uIiA9IGR1cmF0aW9uLCAiQ29ycmVsYXRpb24iID0gY29ycmVsYXRpb24sIG51bSkgJT4lIAogIGdncGxvdChhZXMoeCA9IFNwZWNpZXMsIHkgPSBEdXJhdGlvbiwgZmlsbCA9IFByZWRpY3RvciwgZ3JvdXAgPSBudW0pKSArIAogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuNSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNiksCiAgICAgICAgICAgY29sb3VyID0gImJsYWNrIikgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJjb2xsX3RlbXAiID0gImJsYWNrIiwgIm1heCIgPSAid2hpdGUiLCAibWluIiA9ICJncmV5IikpICsgCiAgbGFicyh4ID0gIiIsIAogICAgICAgeSA9ICJEdXJhdGlvbiBcbihkYXlzKSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKYGBge3IgbWFpbi1maWctYWNjLWNvcnJlbGF0aW9ucywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9OH0KY29ycmVsYXRpb25fY29lZl9wbG90ID0gY29ycl92YWxzICU+JSAgCiAgZmlsdGVyKHNpZyA9PSAiU2lnLiIgfCBwYXJhbWV0ZXIgPT0gImNvbGxfdGVtcCIpICU+JSAKICBkcm9wX25hKGNvcnJlbGF0aW9uKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lCiAgZmlsdGVyKHBhcmFtZXRlciA9PSAiY29sbF90ZW1wIiB8IGNvcnJlbGF0aW9uID09IG1heChjb3JyZWxhdGlvbikpICU+JSAKICBhcnJhbmdlKHNwX25hbWUsIHBhcmFtZXRlcikgJT4lIAogIG11dGF0ZSgibnVtIiA9IHJvd19udW1iZXIoKSkgJT4lIAogIHNlbGVjdCgiU3BlY2llcyIgPSBzcF9uYW1lLCAiUHJlZGljdG9yIiA9IHBhcmFtZXRlciwgIkR1cmF0aW9uIiA9IGR1cmF0aW9uLCAiQ29ycmVsYXRpb24iID0gY29ycmVsYXRpb24sIG51bSkgJT4lIAogIG11dGF0ZShQcmVkaWN0b3IgPSBpZl9lbHNlKFByZWRpY3RvciA9PSAiY29sbF90ZW1wIiwgUHJlZGljdG9yLCAiYmVzdCIpKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBtdXRhdGUoU3BlY2llcyA9IGZjdF9yZW9yZGVyKFNwZWNpZXMsIER1cmF0aW9uLCAuZnVuID0gbWF4LCAuZGVzYyA9IFQpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gU3BlY2llcywgeSA9IENvcnJlbGF0aW9uLCBmaWxsID0gUHJlZGljdG9yLCBncm91cCA9IG51bSkpICsgCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC41LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC42KSwKICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siKSArIAogIGxhYnMoeSA9ICJDb3JyZWxhdGlvbiBcbkNvZWZmaWNpZW50IiwKICAgICAgIGZpbGwgPSAiQ29ycmVsYXRlIikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoImNvbGxfdGVtcCIgPSAiYmxhY2siLCAiYmVzdCIgPSAid2hpdGUiKSkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCAxKSwgbGltaXRzID0gYygwLDEpKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMDAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQoKZ2dhcnJhbmdlKGR1cmF0aW9uX3Bsb3QsIGNvcnJlbGF0aW9uX2NvZWZfcGxvdCwgbnJvdyA9IDIsIGxlZ2VuZCA9ICJyaWdodCIsIGxhYmVscyA9ICJBVVRPIiwKICAgICAgICAgIGhlaWdodHMgPSBjKDAuNCwgMC42KSkKYGBgCgpgYGB7ciBtaXNjLWFjYy1kdXJhdGlvbi1wbG90LCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD00LCBpbmNsdWRlID0gRn0KIyBQaGVub3R5cGljIHZhcmlhdGlvbiAobGlrZSBhY2NsaW1hdGlvbiBvZiB0aGVybWFsIGxpbWl0cykgaXMgYSBwaHlzaW9sb2dpY2FsIHByb2Nlc3MuIGRlcGVuZGluZyBvbiB0aGUgbWVjaGFuaXN0aWMgdW5kZXJwaW5uaW5ncyAoY2hhbmdlcyBpbiBIU1AgZXhwcmVzc2lvbiwgZXRjLiksIHRoZSBhbW91bnQgb2YgdGltZSBpdCB0YWtlcyBmb3IgYW4gaW5kaXZpZHVhbCB0byBhY2NsaW1hdGUgbWF5IHZhcnkgYmFzZWQgb24gYm9keSBzaXplIChsYXJnZXIgc3BlY2llcywgbW9yZSBjZWxscywgbW9yZSB0aW1lIHJlcXVpcmVkIHRvIGFjY2xpbWF0ZSkuIFNob3duIGhlcmUgaXMgdGhlIGR1cmF0aW9uIG9mIHRoZSBlbnZpcm9ubWVudGFsIGFjY2xpbWF0aW9uIHdpbmRvdyB0aGUgY29wZXBvZHMgYXBwZWFyIHRvIGJlIHJlc3BvbmRpbmcgdG8uICAKCm1lYW5fc2l6ZXMgPSBmdWxsX2RhdGEgJT4lIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgIAogIHN1bW1hcmlzZShtZWFuX3NpemUgPSBtZWFuKHNpemUsIG5hLnJtID0gVCkpCgpjb3JyX3ZhbHMgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JSAKICBmaWx0ZXIoY29ycmVsYXRpb24gPT0gbWF4KGNvcnJlbGF0aW9uKSkgJT4lICAKICBpbm5lcl9qb2luKG1lYW5fc2l6ZXMsIGJ5ID0gInNwX25hbWUiKSAlPiUgCiAgc2VsZWN0KHNwX25hbWUsIGR1cmF0aW9uLCBtZWFuX3NpemUpICU+JSAgCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl9zaXplLCB5ID0gZHVyYXRpb24pKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHNwX25hbWUpLCAKICAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJNZWFuIEZlbWFsZSBTaXplIChtbSkiLAogICAgICAgeSA9ICJBY2NsaW1hdGlvbiBEdXJhdGlvbiIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgojIyBUcmFpdCBWYXJpYXRpb24gCgpTaG93biBiZWxvdyBhcmUgdGhlIGNsdXRjaCBzaXplIGRpc3RyaWJ1dGlvbnMgZm9yIHRoZSB0aHJlZSBkaWFwdG9taWlkIHNwZWNpZXMsIHdoaWNoIHByb2R1Y2UgZWdnIHNhY3MgdGhhdCBhbGxvdyBmb3IgZWFzeSBxdWFudGlmaWNhdGlvbiBvZiBmZWN1bmRpdHkuIAoKYGBge3Igc3VwcC1maWctZmVjdW5kaXR5LWhpc3RvZ3JhbSwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9MTB9CmZ1bGxfZGF0YSAlPiUgIAogIGRyb3BfbmEoZmVjdW5kaXR5KSAlPiUgIAogIGdncGxvdChhZXMoeCA9IGZlY3VuZGl0eSwgZmlsbCA9IHNwX25hbWVfc3ViKSkgKyAKICBmYWNldF93cmFwKC5+c3BfbmFtZV9zdWIsIG5jb2wgPSAxKSArIAogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMikgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkZlY3VuZGl0eSAoIyBFZ2dzKSIpICsKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCk9uZSBvZiB0aGUgbWFpbiBhaW1zIG9mIHRoaXMgcHJvamVjdCBpcyB0byBleGFtaW5lIHRoZSBwYXR0ZXJucyBhbmQgcHJvY2Vzc2VzIGRyaXZpbmcgdmFyaWF0aW9uIGluIHVwcGVyIHRoZXJtYWwgbGltaXRzIGFjcm9zcyB0aGVzZSBzcGVjaWVzIG9mIGNvcGVwb2RzLiAKCiMjIyBWYXJpYXRpb24gd2l0aCB0ZW1wZXJhdHVyZSAKCldlIGV4cGVjdCBvbmUgb2YgdGhlIHByaW1hcnkgZHJpdmVycyBvZiBjb3BlcG9kIHRoZXJtYWwgbGltaXRzIHRvIGJlIHRlbXBlcmF0dXJlLCBhcyBpbmRpdmlkdWFscyBhY2NsaW1hdGUgdG8gc2Vhc29uYWwgY2hhbmdlcy4gU2hvd24gYmVsb3cgYXJlIHRoZSBzZWFzb25hbCBwYXR0ZXJucyBvZiB3aGVuIGNvcGVwb2RzIHdlcmUgaW5jbHVkZWQgaW4gQ1RtYXggbWVhc3VyZW1lbnRzIChhIHByb3h5IGZvciB0aGUgc2Vhc29uIG9mIG9jY3VycmVuY2UpLCBhbmQgdGhlcm1hbCBsaW1pdHMgZm9yIGVhY2ggc3BlY2llcyBwbG90dGVkIGFnYWluc3QgdGhlIHRlbXBlcmF0dXJlIGF0IHRoZSB0aW1lIG9mIGNvbGxlY3Rpb24uIFdlIGdlbmVyYWxseSBzZWUgYW4gaW5jcmVhc2UgaW4gdGhlcm1hbCBsaW1pdHMgd2l0aCBpbmNyZWFzaW5nIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUuCgpgYGB7ciBmaWcud2lkdGg9NywgZmlnLmhlaWdodD01fQpzcF9jdG1heF90ZW1wID0gZnVsbF9kYXRhICU+JSAKICBmaWx0ZXIoc3BfbmFtZSAhPSAiT3NwaHJhbnRpY3VtIGxhYnJvbmVjdHVtIikgJT4lIAogIG11dGF0ZShzcF9uYW1lID0gYXMuZmFjdG9yKHNwX25hbWUpLAogICAgICAgICBzcF9uYW1lID0gZmN0X3Jlb3JkZXIoc3BfbmFtZSwgY3RtYXgsIC5kZXNjID0gVCkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBjdG1heCwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4pICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGLCBsaW5ld2lkdGggPSAxLjUsIGNvbG91ciA9ICJncmV5MzAiKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gMC40KSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIiwgCiAgICAgICB5ID0gIkNUbWF4ICjCsEMpIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYAoKVGhlIGludGVyYWN0aW9uIGJldHdlZW4gc2Vhc29uYWwgY2hhbmdlcyBpbiB0ZW1wZXJhdHVyZSBhbmQgdGhlIGFjY2xpbWF0aW9uIG9mIHRoZXJtYWwgbGltaXRzIGxpa2VseSBhZmZlY3RzIHZ1bG5lcmFiaWxpdHkgb2YgZWFjaCBzcGVjaWVzIHRvIHdhcm1pbmcuIFNob3duIGJlbG93IGFyZSB3YXJtaW5nIHRvbGVyYW5jZSB2YWx1ZXMgZm9yIGVhY2ggc3BlY2llcywgY2FsY3VsYXRlZCBhcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGluZGl2aWR1YWwgQ1RtYXggYW5kIHRoZSB0ZW1wZXJhdHVyZSBhdCB0aGUgdGltZSBvZiBjb2xsZWN0aW9uLiBBbGwgc3BlY2llcyBtYWludGFpbmVkIHNvbWUgZGVncmVlIG9mIGJ1ZmZlciBiZXR3ZWVuIGVudmlyb25tZW50YWwgdGVtcGVyYXR1cmVzIGFuZCB1cHBlciB0aGVybWFsIGxpbWl0cywgYnV0ICpMLiBtaW51dHVzKiBhcHBlYXJzIHRvIGFwcHJvYWNoIGl0cyB1cHBlciB0aGVybWFsIGxpbWl0IGR1cmluZyB0aGUgd2FybWVzdCBjb2xsZWN0aW9ucyBkdXJpbmcgdGhlIHN1bW1lci4gCgpBbHNvIHNob3duIGJlbG93IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBmZWN1bmRpdHkgKHRoZSBudW1iZXIgb2YgZWdncyBjb250YWluZWQgaW4gYSBjbHV0Y2gpIGZvciB0aGUgdGhyZWUgZGlhcHRvbWlkIHNwZWNpZXMuIEZvciB0aGUgdHdvIExlcHRvZGlhcHRvbXVzIHNwZWNpZXMsIHRoZXJlIGlzIG5vIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGNsdXRjaCBzaXplIGFuZCB0ZW1wZXJhdHVyZSwgd2hpbGUgdGhlcmUgYXBwZWFycyB0byBiZSBhIGdlbmVyYWwgaW5jcmVhc2UgaW4gY2x1dGNoIHNpemUgd2l0aCB0ZW1wZXJhdHVyZSBpbiB0aGUgU2tpc3RvZGlhcHRvbXVzIHNwZWNpZXMuIAoKYGBge3IgbWFpbi1maWctdHJhaXQtY29sbC10ZW1wLXBsb3RzLCBmaWcud2lkdGg9MTUsIGZpZy5oZWlnaHQ9N30KCnd0X3RlbXAgPSBmdWxsX2RhdGEgJT4lIAogIGZpbHRlcihzcF9uYW1lICE9ICJPc3BocmFudGljdW0gbGFicm9uZWN0dW0iKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gd2FybWluZ190b2wsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMsCiAgICAgICAgICAgICBhbHBoYSA9IDAuMykgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBsaW5ld2lkdGggPSAzKSArCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gVGVtcGVyYXR1cmUgKMKwQykiLCAKICAgICAgIHkgPSAiV2FybWluZyBUb2xlcmFuY2UgKMKwQykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSAgKyAKICB5bGltKDAsMzApICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKZWdnc190ZW1wID0gZnVsbF9kYXRhICU+JSAKICBmaWx0ZXIoc3BfbmFtZSAhPSAiT3NwaHJhbnRpY3VtIGxhYnJvbmVjdHVtIikgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IGZlY3VuZGl0eSwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC4zKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGxpbmV3aWR0aCA9IDMpICsKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgeSA9ICJGZWN1bmRpdHkgKCMgRWdncykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSAgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKZ2dhcnJhbmdlKHd0X3RlbXAsIGVnZ3NfdGVtcCwgCiAgICAgICAgICBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gInJpZ2h0IiwgbGFiZWxzID0gIkFVVE8iKQpgYGAKCmBgYHtyIHN1cHAtZmlnLWxzaWMtbW9ycGhzLCBpbmNsdWRlID0gRn0KbW9ycGhfZGF0YSA9IGZ1bGxfZGF0YSAlPiUgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIiAmIHNwZWNpZXMgPT0gImxlcHRvZGlhcHRvbXVzX3NpY2lsaXMiKSAlPiUgIG11dGF0ZShzcF9uYW1lID0gY2FzZV93aGVuKAogICAgc3BfbmFtZSA9PSAiTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyIgJiBzaXplID49IDAuODkgfiAiTGFyZ2UiLAogICAgc3BfbmFtZSA9PSAiTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyIgJiBzaXplIDwgMC44OSB+ICJTbWFsbCIsCiAgICAuZGVmYXVsdCA9IHNwX25hbWUKICApKQoKZ2dwbG90KG1vcnBoX2RhdGEsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gMC44KSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gVCwgbGluZXdpZHRoID0gMikgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCmBgYHtyIG1pc2MtY3RtYXgtcmFuZ2UtcGxvdCwgaW5jbHVkZSA9IEZ9CmZ1bGxfZGF0YSAlPiUgIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBncm91cF9ieShzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUsIGNvbGxlY3Rpb25fdGVtcCkgJT4lICAKICBzdW1tYXJpc2UoImN0bWF4X3JhbmdlIiA9IG1heChjdG1heCkgLSBtaW4oY3RtYXgpLAogICAgICAgICAgICAiY3RtYXhfdmFyIiA9IHZhcihjdG1heCksCiAgICAgICAgICAgICJzYW1wbGVfc2l6ZSIgPSBuKCkpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JSAKICBmaWx0ZXIoc3BfbmFtZSAhPSAiTGVwdG9kb3JhIGtpbmR0aSIpICU+JSAKICBmaWx0ZXIoc2FtcGxlX3NpemUgPiAzKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXhfdmFyLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LikgKyAKICBnZW9tX3BvaW50KCkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvdXIgPSAiYmxhY2siKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkKYGBgCgpgYGB7ciBjdG1heC1jb2xsLXRlbXAtbW9kZWwsIGluY2x1ZGUgPSBGfQojIGFkdWx0X2RhdGEgPSBmdWxsX2RhdGEgJT4lIAojICAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikKCiMgCiMgY3RtYXhfdGVtcC5tb2RlbCA9IGxtKGRhdGEgPSBtb2RlbF9kYXRhLCBjdG1heCB+IHRlbXBfY2VudCAqIHNwX25hbWUpCiMgc2l6ZV90ZW1wLm1vZGVsID0gbG0oZGF0YSA9IG1vZGVsX2RhdGEsIHNpemUgfiB0ZW1wX2NlbnQgKiBzcF9uYW1lKQojIGZlY3VuZF90ZW1wLm1vZGVsID0gbG0oZGF0YSA9IGRyb3BfbmEobW9kZWxfZGF0YSwgZmVjdW5kaXR5KSwgZmVjdW5kaXR5IH4gdGVtcF9jZW50ICogc3BfbmFtZSkKIyAKIyBmZWN1bmRpdHlfcmVzaWRzID0gY2JpbmQoZHJvcF9uYShtb2RlbF9kYXRhLCBmZWN1bmRpdHkpLCAiZmVjdW5kaXR5X3Jlc2lkcyIgPSBmZWN1bmRfdGVtcC5tb2RlbCRyZXNpZHVhbHMpICU+JSAKIyAgIHNlbGVjdChjb2xsZWN0aW9uX2RhdGUsIGV4cF9kYXRlLCByZXBsaWNhdGUsIHNwZWNpZXMsIHR1YmUsIGZlY3VuZGl0eV9yZXNpZHMpCiMgCiMgY3RtYXhfcmVzaWRzID0gY2JpbmQobW9kZWxfZGF0YSwgInJlc2lkcyIgPSBjdG1heF90ZW1wLm1vZGVsJHJlc2lkdWFscywgInNpemVfcmVzaWRzIiA9IHNpemVfdGVtcC5tb2RlbCRyZXNpZHVhbHMpICU+JSAKIyAgIGxlZnRfam9pbihmZWN1bmRpdHlfcmVzaWRzKQoKYGBgCgpgYGB7ciBzdXBwLWZpZy1jdG1heC10aW1lLWluLWxhYiwgZmlnLndpZHRoPTE1LCBmaWcuaGVpZ2h0PTEwfQojIENvcGVwb2RzIHNwZW50IHNldmVyYWwgZGF5cyBpbiBsYWIgZHVyaW5nIGV4cGVyaW1lbnRzLiBTaG93biBiZWxvdyBhcmUgdGhlIENUbWF4IHJlc2lkdWFscyAodGFrZW4gZnJvbSBhIG1vZGVsIG9mIENUbWF4IGFnYWluc3QgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSkgcGxvdHRlZCBhZ2FpbnN0IHRoZSB0aW1lIHNwZW50IGluIGxhYiBiZWZvcmUgbWVhc3VyZW1lbnRzIHdlcmUgbWFkZS4gSW5kaXZpZHVhbCByZWdyZXNzaW9ucyBhcmUgc2hvd24gZm9yIHRoZSByZXNpZHVhbHMgYWdhaW5zdCBkYXlzIGluIGxhYiBmb3IgZWFjaCBjb2xsZWN0aW9uLiBXZSBjYW4gc2VlIGNsZWFybHkgdGhhdCB0aGVybWFsIGxpbWl0cyBhcmUgZmFpcmx5IHN0YWJsZSBvdmVyIHRpbWUuIAoKCiMgZ2dwbG90KGN0bWF4X3Jlc2lkcywgYWVzKHggPSBkYXlzX2luX2xhYiwgeSA9IHJlc2lkcywgY29sb3VyID0gc3BfbmFtZSwgZ3JvdXAgPSBjb2xsZWN0aW9uX2RhdGUpKSArIAojICAgZmFjZXRfd3JhcChzcF9uYW1lfi4pICsgCiMgICBnZW9tX3BvaW50KHNpemUgPSA0LCBhbHBoYSA9IDAuNSkgKyAKIyAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMSkgKyAKIyAgICNzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwOjUpKSArIAojICAgbGFicyh4ID0gIkRheXMgaW4gbGFiIiwgCiMgICAgICAgIHkgPSAiQ1RtYXggUmVzaWR1YWxzIikgKyAKIyAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAojICAgdGhlbWVfbWF0dF9mYWNldHMoKSArIAojICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCmBgYHtyIHN1cHAtZmlnLW1vZGVsLXBlcmZvcm1hbmNlLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD0xM30KCm1vZGVsX2RhdGEgPSBmdWxsX2RhdGEgJT4lICAKICBkcm9wX25hKHNpemUsIGN0bWF4KSAlPiUgIAogIGZpbHRlcihzcF9uYW1lICE9ICJPc3BocmFudGljdW0gbGFicm9uZWN0dW0iKSAlPiUgCiAgbXV0YXRlKHRlbXBfY2VudCA9IHNjYWxlKGNvbGxlY3Rpb25fdGVtcCwgY2VudGVyID0gVCwgc2NhbGUgPSBGKSwKICAgICAgICAgc2l6ZV9jZW50ID0gc2NhbGUoc2l6ZSwgY2VudGVyID0gVCwgc2NhbGUgPSBGKSkKCm1pbmltYWwubW9kZWwgPSBsbWU0OjpsbWVyKGRhdGEgPSBtb2RlbF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjdG1heCB+IHNwX25hbWUgKyBzZXggKyB0ZW1wX2NlbnQgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxfGRheXNfaW5fbGFiKSkKCmZ1bGwubW9kZWwgPSBsbWU0OjpsbWVyKGRhdGEgPSBtb2RlbF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBjdG1heCB+IHNwX25hbWUqc2V4KnRlbXBfY2VudCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgKDF8ZGF5c19pbl9sYWIpKQoKZHJvcDEoZnVsbC5tb2RlbCwgdGVzdCA9ICJDaGlzcSIpCgpwZXJmb3JtYW5jZTo6dGVzdF9wZXJmb3JtYW5jZShtaW5pbWFsLm1vZGVsLCBmdWxsLm1vZGVsKQpwZXJmb3JtYW5jZTo6Y2hlY2tfbW9kZWwoZnVsbC5tb2RlbCkKCmNhcjo6QW5vdmEoZnVsbC5tb2RlbCwgdHlwZSA9ICJJSUkiKQoKc3BfY3RtYXggPSBlbW1lYW5zOjplbW1lYW5zKGZ1bGwubW9kZWwsIHNwZWNzID0gInNwX25hbWUiKSAlPiUgCiAgZGF0YS5mcmFtZSgpICU+JSAKICBzZWxlY3Qoc3BfbmFtZSwgInNwZWNpZXNfY3RtYXgiID0gZW1tZWFuKQoKbW9kZWxfY29lZnMgPSBlbW1lYW5zOjplbXRyZW5kcyhmdWxsLm1vZGVsLCB2YXIgPSAidGVtcF9jZW50Iiwgc3BlY3MgPSAic3BfbmFtZSIpICU+JSAKICBkYXRhLmZyYW1lKCkgJT4lIAogIGlubmVyX2pvaW4oc3BfY3RtYXgpIAoKY3RtYXhfcmVzaWRzID0gbW9kZWxfZGF0YSAlPiUgCiAgbXV0YXRlKHJlc2lkcyA9IHJlc2lkdWFscyhmdWxsLm1vZGVsKSkKCiN3cml0ZS5jc3YobW9kZWxfY29lZnMsICJPdXRwdXQvRGF0YS9BUlJfZGF0YS5jc3YiKQpgYGAKCmBgYHtyLCBpbmNsdWRlID0gRn0KCm1vcnBoX2NvbXAgPSBmdWxsX2RhdGEgJT4lIAogIGZpbHRlcihzcGVjaWVzID09ICJsZXB0b2RpYXB0b211c19zaWNpbGlzIikgJT4lIAogICBtdXRhdGUobW9ycGggPSBjYXNlX3doZW4oCiAgICBzaXplID49IDAuODkgfiAiTGFyZ2UiLAogICAgc2l6ZSA8IDAuODkgfiAiU21hbGwiKSkgJT4lIAogIHNlbGVjdChjb2xsZWN0aW9uX2RhdGUsIGNvbGxlY3Rpb25fdGVtcCwgY3RtYXgsIHNpemUsIG1vcnBoKQoKbW9ycGgubW9kZWwgPSBsbShkYXRhID0gbW9ycGhfY29tcCwgCiAgICAgICAgICAgICAgICAgY3RtYXggfiBtb3JwaCAqIGNvbGxlY3Rpb25fdGVtcCkKCiNwZXJmb3JtYW5jZTo6Y2hlY2tfbW9kZWwobW9ycGgubW9kZWwpCgpjYXI6OkFub3ZhKG1vcnBoLm1vZGVsKQoKZW1tZWFuczo6ZW1tZWFucyhtb3JwaC5tb2RlbCwgc3BlY3MgPSAibW9ycGgiLCBhdCA9IGxpc3QoY29sbGVjdGlvbl90ZW1wID0gNSkpICU+JSBwYWlycygpCgojIEluZGl2aWR1YWwgc2l6ZSBpcyBzdHJvbmdseSBpbXBhY3RlZCBieSBkZXZlbG9wbWVudGFsIHRlbXBlcmF0dXJlLiBUaGUgcHJlc2VuY2Ugb2YgdHdvIG1vcnBocyBtYXkgcmVmbGVjdCB0d28gZGlmZmVyZW50IGdlbmVyYXRpb25zIHdpdGggZGlmZmVyaW5nIGRldmVsb3BtZW50YWwgY29uZGl0aW9ucy4gVGhlIGxhcmdlIG1vcnBoIGlzIHByZXNlbnQgZHVyaW5nIHRoZSBGYWxsIHdoaWxlIHRoZSBzbWFsbGVyIG1vcnBoIGlzIHByZXNlbnQgZHVyaW5nIHRoZSBXaW50ZXIgYW5kIFNwcmluZy4gSW5kaXZpZHVhbHMgdGhhdCBhcmUgbWF0dXJlIGR1cmluZyB0aGUgRmFsbCB3ZXJlIHByZXN1bWFibHkgYm9ybiBkdXJpbmcgdGhlIHByZXZpb3VzIFdpbnRlci9TcHJpbmcsIGxhcmdlbHkgZGV2ZWxvcGluZyBkdXJpbmcgdGhlIGNvbGRlc3QgdGltZSBvZiB5ZWFyLiBUaGVzZSBpbmRpdmlkdWFscyByZWFwcGVhciBpbiB0aGUgY29tbXVuaXR5IGluIHRoZSBsYXRlIEZhbGwsIHdoZW4gd2F0ZXIgdGVtcGVyYXR1cmVzIGFyZSBzdGlsbCByZWxhdGl2ZWx5IHdhcm0gLSBvZmZzcHJpbmcgcHJvZHVjZWQgYnkgdGhlIGxhcmdlIG1vcnBocyBkdXJpbmcgdGhlIEZhbGwgbWF0dXJlIHVuZGVyIHRoZXNlIHdhcm1lciBjb25kaXRpb25zLCBwcm9kdWNpbmcgdGhlIHNtYWxsZXIgbW9ycGguIFRoZSBlZmZlY3RzIG9mIHRoZXNlIGRldmVsb3BtZW50YWwgZGlmZmVyZW5jZXMgY2FuIGFsc28gYmUgc2VlbiBpbiB0aGUgdGhlcm1hbCBsaW1pdCBkYXRhIC0gdGhlIHNtYWxsZXIgbW9ycGggKHdoaWNoIGRldmVsb3BlZCBhdCBoaWdoZXIgdGVtcGVyYXR1cmVzKSB0ZW5kZWQgdG8gaGF2ZSBoaWdoZXIgdXBwZXIgdGhlcm1hbCBsaW1pdHMgdGhhbiB0aGUgbGFyZ2VyIG1vcnBoICh3aGljaCBkZXZlbG9wZWQgYXQgY29vbGVyIHRlbXBlcmF0dXJlcykuIFRoaXMgc3VnZ2VzdHMgYSBsYXllcmVkIGltcGFjdCBvZiBkZXZlbG9wbWVudGFsIHBoZW5vdHlwaWMgcGxhc3RpY2l0eSBhbmQgYWNjbGltYXRpb24sIHdoaWNoIHRvZ2V0aGVyIHByb2R1Y2UgYSAnYnVtcCcgaW4gTC4gc2ljaWxpcyBDVG1heCBkdXJpbmcgdGhlIGNvbGRlc3QgcGVyaW9kIG9mIHRpbWUuIER1cmluZyB0aGUgRmFsbCBhbmQgZWFybHkgd2ludGVyLCBDVG1heCBtZWFzdXJlbWVudHMgd2VyZSBtYWRlIG9uIGluZGl2aWR1YWxzIGZyb20gdGhlIGxhcmdlIG1vcnBoLCB3aXRoIGFjY2xpbWF0aW9uIHRvIGNvb2xpbmcgZHJpdmluZyBhIGRlY3JlYXNlIGluIENUbWF4LiBFdmVudHVhbGx5LCBpbmRpdmlkdWFscyBmcm9tIHRoZSBzbWFsbCBtb3JwaCBtYXR1cmUgYW5kIHJlcGxhY2UgdGhlIHByZXZpb3VzIGdlbmVyYXRpb24uIFRoaXMgcmVzdWx0cyBpbiBhbiBhcHBhcmVudCBpbmNyZWFzZSBpbiBDVG1heCBqdXN0IGJlZm9yZSB0aGUgY29sZGVzdCB0aW1lIG9mIHllYXIsIGRyaXZlbiBieSB0aGUgZWZmZWN0cyBvZiBkZXZlbG9wbWVudGFsIHBsYXN0aWNpdHkuIFN1cmZhY2Ugd2F0ZXJzIGNvbnRpbnVlIHRvIGNvb2wsIHdpdGggYWNjbGltYXRpb24gdGhlbiBkcml2aW5nIGEgc21hbGwgZGVjcmVhc2UgaW4gQ1RtYXguIAoKYGBgCgoKYGBge3IgbWFpbi1maWctQVJSLXN5bnRoLXBsb3QsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTZ9CmFycl9jb21iaW5lZCA9IHN5bnRoX2FyciAlPiUKICBmaWx0ZXIobWVhc3VyZSA9PSAidXBwZXIiICYgbWVhbl9saW0gPiAyMCkgJT4lIAogIHNlbGVjdCgiZ3JvdXAiID0gZ2VudXMsIGFyciwgbWVhbl9saW0pICU+JSAKICBtdXRhdGUoImRhdGFzZXQiID0gInN5bnRoZXNpcyIpICU+JSAKICBiaW5kX3Jvd3MoCiAgICBzZWxlY3QobW9kZWxfY29lZnMsICJncm91cCIgPSBzcF9uYW1lLCAnYXJyJyA9IHRlbXBfY2VudC50cmVuZCwgJ21lYW5fbGltJyA9IHNwZWNpZXNfY3RtYXgpCiAgKSAlPiUgCiAgbXV0YXRlKGRhdGFzZXQgPSBpZl9lbHNlKGlzLm5hKGRhdGFzZXQpLCAibmV3IGRhdGEiLCAic3ludGhlc2lzIiksCiAgICAgICAgIGdyb3VwID0gZmN0X3Jlb3JkZXIoZ3JvdXAsIGFyciwgLmRlc2MgPSBUKSkKCgpnZ3Bsb3QoYXJyX2NvbWJpbmVkLCBhZXMoeCA9IG1lYW5fbGltLCB5ID0gYXJyKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIsIGNvbG91ciA9ICJncmV5MzAiKSArIAogIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihhcnJfY29tYmluZWQsIGRhdGFzZXQgIT0gIm5ldyBkYXRhIiksIAogICAgICAgICAgICAgc2l6ZSA9IDMsIGNvbG91ciA9ICJibGFjayIsIHNoYXBlID0gMSwgc3Ryb2tlID0gMS40KSArIAogIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihhcnJfY29tYmluZWQsIGRhdGFzZXQgPT0gIm5ldyBkYXRhIiksCiAgICAgICAgICAgICBhZXMoY29sb3VyID0gZ3JvdXApLCAKICAgICAgICAgICAgIHNpemUgPSA0LjUpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIlRoZXJtYWwgTGltaXQiLCAKICAgICAgIHkgPSAiQVJSIiwgCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKYGBgCgojIyMgU2V4IGFuZCBzdGFnZSB2YXJpYXRpb24gaW4gdGhlcm1hbCBsaW1pdHMgClByZXZpb3VzIHNlY3Rpb25zIGhhdmUgZ2VuZXJhbGx5IGx1bXBlZCBqdXZlbmlsZSwgZmVtYWxlLCBhbmQgbWFsZSBpbmRpdmlkdWFscyB0b2dldGhlci4gVGhlcmUgbWF5IGJlIGltcG9ydGFudCBzdGFnZS0gb3Igc2V4LXNwZWNpZmljIGRpZmZlcmVuY2VzIGluIENUbWF4IHRob3VnaC4gRm9yIGFsbCBzcGVjaWVzIGJ1dCBPc3BocmFudGljdW0sIHdlIGhhdmUgbWVhc3VyZW1lbnRzIGZvciBpbmRpdmlkdWFscyBpbiBkaWZmZXJlbnQgc3RhZ2VzIGFuZCBvZiBkaWZmZXJlbnQgc2V4ZXMuIAoKYGBge3Igc2V4LXN0YWdlLXRhYmxlfQpzZXhfc2FtcGxlX3NpemVzID0gZnVsbF9kYXRhICU+JSAgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgc2V4KSAlPiUgIAogIHN1bW1hcmlzZShudW0gPSBuKCkpICU+JSAgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IHNwX25hbWUsCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IHNleCwgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBudW0sCiAgICAgICAgICAgICAgdmFsdWVzX2ZpbGwgPSAwKSAlPiUgCiAgc2VsZWN0KCJTcGVjaWVzIiA9IHNwX25hbWUsICJKdXZlbmlsZSIgPSBqdXZlbmlsZSwgIkZlbWFsZSIgPSBmZW1hbGUsICJNYWxlIiA9IG1hbGUpCgprbml0cjo6a2FibGUoc2V4X3NhbXBsZV9zaXplcywgYWxpZ24gPSAiYyIpCmBgYAoKQWNyb3NzIGdyb3VwIGNvbXBhcmlzb25zIHNob3cgdGhhdCB0aGVyZSBhcmUgZ2VuZXJhbGx5IG5vIGRpZmZlcmVuY2VzIGluIHRoZXJtYWwgbGltaXRzIChyZXByZXNlbnRlZCBoZXJlIGFzIHRoZSByZXNpZHVhbHMgZnJvbSBhIENUbWF4IH4gY29sbGVjdGlvbl90ZW1wIHggc3BlY2llcyBsaW5lYXIgcmVncmVzc2lvbiksIHdpdGggdGhlIGV4Y2VwdGlvbiBvZiBTZW5lY2VsbGEgbWFsZXMsIHdoaWNoIG1heSBoYXZlIGxvd2VyIHRoZXJtYWwgbGltaXRzIChhbHRob3VnaCBzYW1wbGUgc2l6ZXMgYXJlIHZlcnkgc21hbGwgaW4gdGhpcyBncm91cCkuCgpgYGB7ciBzdXBwLWZpZy1jdG1heC1zZXgsIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD04fQojIGN0bWF4X3Jlc2lkcyAlPiUgCiMgICBmaWx0ZXIoc3BfbmFtZSAhPSAiT3NwaHJhbnRpY3VtIGxhYnJvbmVjdHVtIikgJT4lIAojICAgZ2dwbG90KGFlcyh4ID0gc2V4LCB5ID0gcmVzaWRzLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKIyAgIGZhY2V0X3dyYXAoc3BfbmFtZX4uKSArIAojICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjEsIGFscGhhID0gMC41KSArIAojICAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC40LCBmaWxsID0gTkEsIGNvbG91ciA9ICJibGFjayIsIAojICAgICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEsIG91dGxpZXIuY29sb3VyID0gTkEpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKIyAgIHRoZW1lX21hdHRfZmFjZXRzKCkKYGBgCgpgYGB7ciB0cmFpdC12YXJpYW5jZS1jb2xsLXRlbXAsIGluY2x1ZGUgPSBGfQojIAojIEdpdmVuIHRoZSBsb25nIGdlbmVyYXRpb24gdGltZXMgb2YgdGhlc2UgY29wZXBvZHMsIGRlY3JlYXNlcyBpbiB0cmFpdCB2YXJpYW5jZSBtYXkgaW5kaWNhdGUgc2VsZWN0aW9uIG92ZXIgdGhlIHNlYXNvbmFsIGN5Y2xlLiBTaG93biBiZWxvdyBhcmUgdGhlIHZhcmlhbmNlIGluIG9ic2VydmVkIENUbWF4IGFuZCBzaXplLCBwbG90dGVkIGFnYWluc3QgY29sbGVjdGlvbiBkYXRlLiBWYXJpYW5jZSBkZWNyZWFzZXMgaW4gKlNraXN0b2RpYXB0b211cyosIGJ1dCB0aGlzIHBhdHRlcm4gaXMgZHJpdmVuIGJ5IGEgc2luZ2xlIGNvbGxlY3Rpb24gd2l0aCBoaWdoIHZhcmlhbmNlIGVhcmx5IGluIHRoZSB5ZWFyLiBTaXplIHZhcmlhbmNlIGluY3JlYXNlcyBzbGlnaHRseSBpbiAqU2tpc3RvZGlhcHRvbXVzKi4gVmFyaWFuY2UgaW4gYm90aCBDVG1heCBhbmQgc2l6ZSBpcyBmYWlybHkgY29uc3RhbnQgaW4gKkxlcHRvZGlhcHRvbXVzIG1pbnV0dXMqLCB0aGUgb25seSBvdGhlciBzcGVjaWVzIGNvbGxlY3RlZCBhY3Jvc3MgdGhlIGVudGlyZSBzZXQgb2Ygc2FtcGxlcyB0aHVzIGZhci4gCiMgCiMgZ2dwbG90KGRyb3BfbmEoYWR1bHRfc3VtbWFyaWVzLCBjdG1heF92YXIpLCBhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IGN0bWF4X3ZhciwgY29sb3VyID0gc3BfbmFtZSkpICsgCiMgICBmYWNldF93cmFwKHNwX25hbWV+Liwgc2NhbGVzID0gImZyZWVfeSIpICsgCiMgICBnZW9tX3BvaW50KHNpemUgPSAyKSArIAojICAgZ2VvbV9zbW9vdGgoc2UgPSBGKSArIAojICAgbGFicyh4ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiLCAKIyAgICAgICAgeSA9ICJDVG1heCBWYXJpYW5jZSIpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKIyAgIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKIyAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKIyAKIyBnZ3Bsb3QoZHJvcF9uYShhZHVsdF9zdW1tYXJpZXMsIHNpemVfdmFyKSwgYWVzKHggPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBzaXplX3ZhciwgY29sb3VyID0gc3BfbmFtZSkpICsgCiMgICBmYWNldF93cmFwKHNwX25hbWV+LikgKyAKIyAgIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgCiMgICBnZW9tX3Ntb290aChzZSA9IEYpICsgCiMgICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIsIAojICAgICAgICB5ID0gIlNpemUgVmFyaWFuY2UiKSArIAojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiMgICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiMgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYAoKYGBge3Igc3VwcC1maWctbW9kZWwyLXBlcmZvcm1hbmNlLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD0xM30KbW9kZWwyX2RhdGEgPSBtb2RlbF9kYXRhICU+JSAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiLCAKICAgICAgICAgcGF0aG9nZW4gIT0gInVuY2VydGFpbiIsIAogICAgICAgICBkZXZfZWdncyAhPSAidW5jZXJ0YWluIiwgCiAgICAgICAgIGxpcGlkcyAhPSAidW5jZXJ0YWluIikgJT4lIAogIG11dGF0ZShwYXRob2dlbnMgPSBmY3RfcmVsZXZlbChwYXRob2dlbiwgIm5vIiwgInNwb3QiLCAiY2xvdWR5IiwgIm90aGVyIikpCgpvdGhlcl9mYWN0b3JfbW9kZWwgPSBsbWVyKGRhdGEgPSBtb2RlbDJfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3RtYXh+c3BfbmFtZSAqIGNvbGxlY3Rpb25fdGVtcCArIGRldl9lZ2dzICsgcGF0aG9nZW4gKyBsaXBpZHMgKyAoMXxkYXlzX2luX2xhYikpCgpkcm9wMShvdGhlcl9mYWN0b3JfbW9kZWwsIHNjb3BlID0gfi4sIHRlc3QgPSAiQ2hpc3EiKQoKcmVkdWNlZF9mYWN0b3JzX21vZGVsID0gbG1lcihkYXRhID0gbW9kZWwyX2RhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGN0bWF4fnNwX25hbWUgKiBjb2xsZWN0aW9uX3RlbXAgKyBwYXRob2dlbiArICgxfGRheXNfaW5fbGFiKSkKCnBlcmZvcm1hbmNlOjpjaGVja19tb2RlbChyZWR1Y2VkX2ZhY3RvcnNfbW9kZWwpCgpjYXI6OkFub3ZhKHJlZHVjZWRfZmFjdG9yc19tb2RlbCwgdHlwZSA9ICJJSUkiKQpgYGAKCmBgYHtyIHN1cHAtZmlnLXBhdGhvZ2VuLWVmZmVjdCwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NX0KZW1tZWFuczo6ZW1tZWFucyhyZWR1Y2VkX2ZhY3RvcnNfbW9kZWwsIHNwZWMgPSAicGF0aG9nZW4iKSAlPiUgZW1tZWFuczo6Y29udHJhc3QobWV0aG9kPSJ0cnQudnMuY3RybCIscmVmPSJubyIpICU+JSBwbG90KCkgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArIAogIGxhYnMoeCA9ICJEaWZmZXJlbmNlICjCsEMpIiwgCiAgICAgICB5ID0gIkNvbXBhcmlzb24iKSArIAogICAgdGhlbWVfbWF0dCgpCmBgYAoKCgojIyMgVHJhaXQgQ29ycmVsYXRpb25zIGFuZCBUcmFkZS1vZmZzCgpBIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHNpemUgYW5kIHVwcGVyIHRoZXJtYWwgbGltaXRzIGhhcyBiZWVuIHN1Z2dlc3RlZCBpbiBhIHdpZGUgcmFuZ2Ugb2Ygb3RoZXIgdGF4YS4gU2hvd24gYmVsb3cgYXJlIHRoZSBtZWFzdXJlZCB1cHBlciB0aGVybWFsIGxpbWl0cyBwbG90dGVkIGFnYWluc3QgcHJvc29tZSBsZW5ndGguIFRoZSBvdmVyYWxsIHJlbGF0aW9uc2hpcCAoaW5jbHVzaXZlIG9mIGFsbCBzcGVjaWVzKSBpcyBzaG93biBhcyB0aGUgYmxhY2sgbGluZSBpbiB0aGUgYmFja2dyb3VuZC4gUmVncmVzc2lvbnMgZm9yIGVhY2ggaW5kaXZpZHVhbCBzcGVjaWVzIGFyZSBhbHNvIHNob3duLiBBY3Jvc3MgdGhlIGVudGlyZSBhc3NlbWJsYWdlLCB0aGVyZSBpcyBhIHN0cm9uZyBkZWNyZWFzZSBpbiB0aGVybWFsIGxpbWl0cyB3aXRoIGluY3JlYXNpbmcgc2l6ZS4gIAoKYGBge3IgbWlzYy1jdG1heC1zaXplLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9N30KZnVsbF9kYXRhICU+JSAKICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lICAKICBnZ3Bsb3QoIGFlcyh4ID0gc2l6ZSwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyLCBhbHBoYSA9IDAuMykgKyAKICBnZW9tX3Ntb290aChkYXRhID0gZnVsbF9kYXRhLCAKICAgICAgICAgICAgICBhZXMoeCA9IHNpemUsIHkgPSBjdG1heCksCiAgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgCiAgICAgICAgICAgICAgY29sb3VyID0iYmxhY2siLCAKICAgICAgICAgICAgICBsaW5ld2lkdGggPSAyLjUpICsgCiAgbGFicyh4ID0gIkxlbmd0aCAobW0pIiwgCiAgICAgICB5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKYGBgCgpTaG93biBoZXJlIGlzIHRoZSByZWxhdGlvbnNoaXAgZm9yIGVhY2ggc3BlY2llcyBpbmRpdmlkdWFsbHkuIAoKYGBge3IgbWlzYy1pbmQtc3AtY3RtYXgtc2l6ZSwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9Nn0KZnVsbF9kYXRhICU+JSAKICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lICAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgZmlsdGVyKG4oKSA+MikgJT4lIGZpbHRlcighc3RyX2RldGVjdChzcF9uYW1lLCBwYXR0ZXJuID0gImtpbmR0aSIpKSAlPiUgCiAgZ2dwbG90KCBhZXMoeCA9IHNpemUsIHkgPSBjdG1heCwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4sIHNjYWxlcyA9ICJmcmVlIiwgbnJvdyA9IDIpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjgpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGLCBsaW5ld2lkdGggPSAyKSArIAogIGxhYnMoeCA9ICJMZW5ndGggKG1tKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKClNob3duIGJlbG93IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtZWFuIHNpemUgYW5kIG1lYW4gdGhlcm1hbCBsaW1pdHMgZm9yIGZlbWFsZXMgb2YgZWFjaCBzcGVjaWVzLiBXZSBzZWUgdGhhdCBsYXJnZXIgc3BlY2llcyB3aXRoaW4gdGhlIGNvbW11bml0eSB0ZW5kIHRvIGhhdmUgYSBsb3dlciB0aGVybWFsIGxpbWl0IHRoYW4gc21hbGxlciBzcGVjaWVzLiAKCmBgYHtyIG1haW4tZmlnLW1lYW4tY3RtYXgtbWVhbi1zaXplLXBsb3QsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTV9CmZ1bGxfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgc2V4KSAlPiUgCiAgc3VtbWFyaXplKG1lYW5fY3RtYXggPSBtZWFuKGN0bWF4LCBuYS5ybSA9IFQpLAogICAgICAgICAgICBtZWFuX3NpemUgPSBtZWFuKHNpemUsIG5hLnJtID0gVCkpICU+JSAKICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdncGxvdChhZXMoeCA9IG1lYW5fc2l6ZSwgeSA9IG1lYW5fY3RtYXgpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMiwgY29sb3VyID0gImJsYWNrIikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzcF9uYW1lLCBzaGFwZSA9IHNleCksCiAgICAgICAgICAgICBzaXplID0gNSkgKyAKICBsYWJzKHggPSAiTGVuZ3RoIChtbSkiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKYGBge3IgY3RtYXhyZXNpZHMtc2l6ZSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTcsIGluY2x1ZGUgPSBGfQojIGN0bWF4X3Jlc2lkcyAlPiUgCiMgICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAojICAgZ2dwbG90KGFlcyh4ID0gc2l6ZSwgeSA9IHJlc2lkcywgY29sb3VyID0gc3BfbmFtZSkpICsgCiMgICBmYWNldF93cmFwKHNwX25hbWV+LikgKyAKIyAgIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgCiMgICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiMgICBsYWJzKHggPSAiTGVuZ3RoIChtbSkiLCAKIyAgICAgICAgeSA9ICJDVG1heCAowrBDKSIpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKIyAgIHRoZW1lX21hdHQoKSArIAojICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKClNob3duIGhlcmUgaXMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGZlY3VuZGl0eSBhbmQgc2l6ZSwgc2hvd2luZyB0aGUgY2xhc3NpYyBwYXR0ZXJuIG9mIGluY3JlYXNpbmcgZWdnIHByb2R1Y3Rpb24gd2l0aCBpbmNyZWFzaW5nIHNpemUuIAoKYGBge3IgZmVjdW5kaXR5LXNpemV9CnNpemVfZmVjdW5kX3Bsb3QgPSBjdG1heF9yZXNpZHMgJT4lICAKICBkcm9wX25hKGZlY3VuZGl0eSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHNpemUsIHkgPSBmZWN1bmRpdHksIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyLCBhbHBoYSA9IDAuNSkgKyAKICBsYWJzKHggPSAiUHJvc29tZSBsZW5ndGggKG1tKSIsIAogICAgICAgeSA9ICJGZWN1bmRpdHkgKCMgRWdncykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKSW5kaXZpZHVhbHMgbWF5IGFsc28gYWxsb2NhdGUgZW5lcmd5IHRvIGRpZmZlcmVudCBmaXRuZXNzIHJlbGF0ZWQgdHJhaXRzLCBwcmlvcml0aXppbmcgcmVwcm9kdWN0aXZlIG91dHB1dCBvdmVyIGVudmlyb25tZW50YWwgdG9sZXJhbmNlLCBmb3IgZXhhbXBsZS4gU2hvd24gYmVsb3cgaXMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIENUbWF4IHJlc2lkdWFscyAoYWdhaW4sIGNvbnRyb2xsaW5nIGZvciB0aGUgZWZmZWN0cyBvZiBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlKSBhZ2FpbnN0IGZlY3VuZGl0eS4gV2UgY2FuIHNlZSBjbGVhcmx5IHRoYXQgaW5kaXZpZHVhbHMgd2l0aCBpbmNyZWFzZWQgZmVjdW5kaXR5IGFyZSBub3QgZGVjcmVhc2luZyB0aGVybWFsIGxpbWl0cywgc3VnZ2VzdGluZyB0aGF0IHRoZXJlIGlzIG5vIGVuZXJnZXRpYyB0cmFkZS1vZmYgYmV0d2VlbiB0aGVzZSB0cmFpdHMuIApgYGB7ciwgbWFpbi1maWctZmVjdW5kaXR5LXBsb3RzLCBmaWcud2lkdGg9OC41LCBmaWcuaGVpZ2h0PTEwfQpjdG1heF9mZWN1bmRfcGxvdCA9IGN0bWF4X3Jlc2lkcyAlPiUgIAogIGRyb3BfbmEoZmVjdW5kaXR5KSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcmVzaWRzLCB5ID0gZmVjdW5kaXR5LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjUpICsgCiAgbGFicyh4ID0gIkNUbWF4IFJlc2lkdWFscyAowrBDKSIsIAogICAgICAgeSA9ICJGZWN1bmRpdHkgKCMgRWdncykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2Uoc2l6ZV9mZWN1bmRfcGxvdCwgY3RtYXhfZmVjdW5kX3Bsb3QsIG5jb2wgPSAxLCBjb21tb24ubGVnZW5kID0gVCwgbGFiZWxzID0gIkFVVE8iLCBsZWdlbmQgPSAicmlnaHQiKQpgYGAKClByZXZpb3VzIHN0dWRpZXMgaGF2ZSBzaG93biB0aGF0IHRoZSBtYWduaXR1ZGUgb2YgdGhlIHNpemUtZmVjdW5kaXR5IGNvcnJlbGF0aW9uIG1heSBiZSBlbnZpcm9ubWVudGFsbHktZGVwZW5kZW50LiBUaGlzIGlzIG5vdCB2aXNpYmxlIGlzIHRoZSBkYXRhIGZyb20gdGhlc2UgY29sbGVjdGlvbnMuIAoKYGBge3Igc3VwcC1maWctZmVjLXNpemUtY29yci12cy10ZW1wLCBmaWcud2lkdGggPSA0LCBmaWcuaGVpZ2h0PTEwfQpjb3JyX2RhdGEgPSBmdWxsX2RhdGEgJT4lIAogIGRyb3BfbmEoZmVjdW5kaXR5KSAlPiUgCiAgZmlsdGVyKHNwX25hbWUgJWluJSBjKCJMZXB0b2RpYXB0b211cyBzaWNpbGlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgIkxlcHRvZGlhcHRvbXVzIG1pbnV0dXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgIlNraXN0b2RpYXB0b211cyBzcCIpKSAlPiUgIAogIGdyb3VwX2J5KGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wLCBzcF9uYW1lKSAlPiUgCiAgc3VtbWFyaXNlKHNpemVfZmVjX2NvcnIgPSBjb3Ioc2l6ZSwgZmVjdW5kaXR5KSwKICAgICAgICAgICAgbiA9IG4oKSwKICAgICAgICAgICAgbWVhbl9mZWN1bmRpdHkgPSBtZWFuKGZlY3VuZGl0eSkpICU+JSAKICBmaWx0ZXIobiA+PSAzKSAlPiUgCiAgdW5ncm91cCgpICU+JSAgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lIAogIG11dGF0ZSh0ZW1wX2NlbnQgPSBzY2FsZShjb2xsZWN0aW9uX3RlbXAsIHNjYWxlID0gRikpCgpnZ3Bsb3QoY29ycl9kYXRhLCBhZXMoeCA9IHRlbXBfY2VudCwgeSA9IHNpemVfZmVjX2NvcnIsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBucm93ID0gMykgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBsaW5ld2lkdGggPSAyKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIlRlbXBlcmF0dXJlIChjZW50ZXJlZCkiLCAKICAgICAgIHkgPSAiQ29ycmVsYXRpb24gQ29lZmZpY2llbnQiKSArIAogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygtMSwgMSkpICsKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKIyBnZ3Bsb3QoY29ycl9kYXRhLCBhZXMoeCA9IHNpemVfZmVjX2NvcnIpKSArCiMgICAgIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBucm93ID0gMykgKwojICAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjIpCmBgYAoKCiMjIE90aGVyIHBhdHRlcm5zIGluIHZhcmlhdGlvbiAKCipMZXB0b2RpYXB0b211cyBzaWNpbGlzKiBpcyB0aGUgbW9zdCBhYnVuZGFudCBzcGVjaWVzIGR1cmluZyB0aGUgd2ludGVyLiBUaGVyZSB3YXMgYSBsYXJnZSBzaGlmdCBpbiB0aGUgc2l6ZSBvZiBtYXR1cmUgZmVtYWxlcyB0b3dhcmRzIHRoZSBlbmQgb2YgRGVjZW1iZXIuIFRoZXNlIGxhcmdlIGFuZCBzbWFsbCBpbmRpdmlkdWFscyBhcmUgdGhlIHNhbWUgc3BlY2llcyAoY29uZmlybWVkIHZpYSBDT0kgc2VxdWVuY2luZyksIHN1Z2dlc3RpbmcgdGhpcyBzaGlmdCBtYXkgaW5zdGVhZCByZWZsZWN0IGEgdHJhbnNpdGlvbiBmcm9tIG9uZSBnZW5lcmF0aW9uIHRvIGFub3RoZXIuIFRoaXMgc2l6ZSBkaWZmZXJlbmNlIG1heSBiZSBjYXVzZWQgYnkgZGlmZmVyZW5jZXMgaW4gdGhlIGRldmVsb3BtZW50YWwgZW52aXJvbm1lbnRzLiBGb3IgZXhhbXBsZSwgaW5kaXZpZHVhbHMgZGV2ZWxvcGluZyBpbiBKYW51YXJ5IGdyb3cgdXAgYXQgdmVyeSBsb3cgdGVtcGVyYXR1cmVzLCBhbmQgdGhlcmVmb3JlIG1heSByZWFjaCBsYXJnZXIgc2l6ZXMuIFRoZXNlIGluZGl2aWR1YWxzIG92ZXItc3VtbWVyIGluIGRlZXAgd2F0ZXJzLCB0aGVuIHJlLWVtZXJnZSBpbiBPY3RvYmVyIGFuZCBwcm9kdWNlIGEgbmV3IGdlbmVyYXRpb24uIFdhdGVyIHRlbXBlcmF0dXJlcyBhcmUgc3RpbGwgZmFpcmx5IGhpZ2ggdGhyb3VnaCBOb3ZlbWJlciwgd2hpY2ggcmVzdWx0cyBpbiBhIGdlbmVyYXRpb24gb2Ygc21hbGxlciBpbmRpdmlkdWFscy4gVGhlc2UgaW5kaXZpZHVhbHMgbWF0dXJlIGluIHRpbWUgdG8gcHJvZHVjZSBhIG5ldyBnZW5lcmF0aW9uIGluIEphbnVhcnkuIAoKYGBge3Igc3VwcC1maWctbHNpYy1tb3JwaC1zaXplLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD05fQpmdWxsX2RhdGEgJT4lICAKICBmaWx0ZXIoc3BfbmFtZSA9PSAiTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyIpICU+JSAKICBmaWx0ZXIoc2V4ICE9ICJqdXZlbmlsZSIpICU+JSAKICBncm91cF9ieShjb2xsZWN0aW9uX2RhdGUpICU+JSAKICBtdXRhdGUoc2l6ZV9jZW50ZXIgPSBzY2FsZShzaXplLCBjZW50ZXIgPSBULCBzY2FsZSA9IEYpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmFjdG9yKGNvbGxlY3Rpb25fZGF0ZSksIHggPSBzaXplLCBmaWxsID0gY29sbGVjdGlvbl90ZW1wKSkgKyAKICBmYWNldF93cmFwKHNleH4uKSArIAogIGdlb21fZGVuc2l0eV9yaWRnZXMoYmFuZHdpZHRoID0gMC4wNCkgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLjg5KSArIAogIGxhYnMoeCA9ICJTaXplIChtbSkiLAogICAgICAgeSA9ICJEYXRlIiwgCiAgICAgICBmaWxsID0gIkNvbGwuIFRlbXAuICjCsEMpIikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpCmBgYAoKQSBzaW1pbGFyLCBidXQgbGVzcyBkaXN0aW5jdCBwYXR0ZXJuIGNhbiBiZSBvYnNlcnZlZCBpbiBMLiBtaW51dHVzIGluZGl2aWR1YWxzIGFzIHdlbGwuIApgYGB7ciBzdXBwLWZpZy1sbWluLW1vcnBoLXNpemUsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTl9CmZ1bGxfZGF0YSAlPiUgIAogIGZpbHRlcihzcF9uYW1lID09ICJMZXB0b2RpYXB0b211cyBtaW51dHVzIikgJT4lIAogIGZpbHRlcihzZXggIT0gImp1dmVuaWxlIikgJT4lIAogIGdncGxvdChhZXMoeSA9IGZhY3Rvcihjb2xsZWN0aW9uX2RhdGUpLCB4ID0gc2l6ZSwgZmlsbCA9IGNvbGxlY3Rpb25fdGVtcCkpICsgCiAgZmFjZXRfd3JhcChzZXh+LikgKyAKICBnZW9tX2RlbnNpdHlfcmlkZ2VzKGJhbmR3aWR0aCA9IDAuMDQpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMC42OSkgKyAKICBsYWJzKHggPSAiU2l6ZSAobW0pIiwKICAgICAgIHkgPSAiRGF0ZSIsIAogICAgICAgZmlsbCA9ICJDb2xsLiBUZW1wLiAowrBDKSIpICsgCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDAuNSwwLjkpKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKYGBgCgojIyBEaXN0cmlidXRpb24gTGFnIE5vbi1MaW5lYXIgTW9kZWwgKERMTk0gYXBwcm9hY2gpIAoKRGlzdHJpYnV0ZWQgbGFnIG1vZGVscyBleGFtaW5lIGEgcmVzcG9uc2UgdmFyaWFibGUsIG1lYXN1cmVkIGF0IG11bHRpcGxlIHRpbWUgcG9pbnRzLCBhcyBhIGZ1bmN0aW9uIG9mIHRoZSBsYWdnZWQgb2NjdXJyZW5jZSBvZiBzb21lIHByZWRpY3RvciB2YXJpYWJsZSAocmVzcG9uc2UgeSBhdCB0aW1lIHQgYXMgYSBmdW5jdGlvbiBvZiBwcmVkaWN0b3IgeCh0LWxhZykuIFRoaXMgbWV0aG9kIHV0aWxpemVzIGEgYmktZGltZW5zaW9uYWwgZG9zZS1sYWctcmVzcG9uc2UgZnVuY3Rpb24sIHdoaWNoIGVzc2VudGlhbGx5IGV4YW1pbmVzIG5vdCBvbmx5IHRoZSBkb3NlIGVmZmVjdCwgYnV0IHRoZSBlZmZlY3Qgb2YgdGhlIHRpbWluZyBvZiB0aGUgZG9zZS4gCgoKYGBge3IgY29tcGlsaW5nX3RlbXBfbGFnc30KIyBSdW4gdGhpcyBjb2RlLCBzYXZlIHRoZSBwcm9kdWN0LCBhbmQgdGhlbiBqdXN0IHJlYWQgaW4gdGhlIHRlbXAgbGFnIGRhdGEgb2JqZWN0LiBUYWtlcyB0b28gbG9uZyB0byBydW4gZWFjaCB0aW1lIHRoaXMgZG9jdW1lbnQgaXMga25pdC4gCgojIGxhZ190ZW1wcyA9IHRlbXBfZGF0YSAlPiUKIyAgIGdyb3VwX2J5KGRhdGUsIGhvdXIpICU+JQojICAgc3VtbWFyaXplKCJtZWFuX3RlbXAiID0gbWVhbih0ZW1wLCBuYS5ybSA9IFQpKSAlPiUKIyAgIHVuZ3JvdXAoKSAlPiUKIyAgIG11dGF0ZShwb2ludF9udW0gPSByb3dfbnVtYmVyKCkpCiMgCiMgdW5pcV9kYXlzID0gbGVuZ3RoKHVuaXF1ZShsYWdfdGVtcHMkZGF0ZSkpCiMgCiMgZyA9IGdhbShtZWFuX3RlbXAgfiBzKHBvaW50X251bSwgYnM9ImNyIiwgaz11bmlxX2RheXMgKyAxMCksCiMgICAgIG1ldGhvZCA9ICJSRU1MIiwKIyAgICAgZGF0YSA9IGxhZ190ZW1wcykKIyAKIyBwb2ludHMgPSBzZXEoMSwgbnJvdyhsYWdfdGVtcHMpLCBsZW5ndGgub3V0ID0gbGVuZ3RoKGxhZ190ZW1wcyRob3VyKSkKIyAKIyBkZi5yZXMgPSBkZi5yZXNpZHVhbChnKQojIAojIHByZWRfdGVtcHMgPSBwcmVkaWN0KGcsIG5ld2RhdGEgPSBsYWdfdGVtcHMsIHR5cGUgPSAicmVzcG9uc2UiLCBzZS5maXQgPSBUUlVFKQojIAojIGxhZ190ZW1wcyA9IGxhZ190ZW1wcyAlPiUKIyAgIG11dGF0ZSh0cmVuZF9UID0gcHJlZF90ZW1wcyRmaXQsCiMgICAgICAgICAgdHJlbmRfc2UgPSBwcmVkX3RlbXBzJHNlLmZpdCwKIyAgICAgICAgICB0ZW1wX2RpZmYgPSBtZWFuX3RlbXAgLSB0cmVuZF9UKQojIAojIHdyaXRlLmNzdihsYWdfdGVtcHMsIGZpbGUgPSAiLi9PdXRwdXQvRGF0YS9sYWdfdGVtcHMuY3N2Iiwgcm93Lm5hbWVzID0gRikKCmBgYAoKYGBge3Igc3VwcC1maWctZGFpbHktbWF4LWN0bWF4LCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD00fSAKCmRsbm1fZGF0YSA9IGZ1bGxfZGF0YSAlPiUgIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBmaWx0ZXIoc3BfbmFtZSAlaW4lIGMoCiAgICAiTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyIsCiAgICAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyIKICApKSAlPiUgCiAgc2VsZWN0KGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wLCBzcF9uYW1lLCBjdG1heCkgJT4lIAogIGdyb3VwX2J5KGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wLCBzcF9uYW1lKSAlPiUgIAogIHN1bW1hcmlzZShtZWFuX2N0bWF4ID0gbWVhbihjdG1heCwgbmEucm0gPSBUKSwKICAgICAgICAgICAgc2FtcGxlID0gbigpKQoKdGVtcF9kYXRhICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fdGVtcCA9IG1lYW4odGVtcCksCiAgICAgICAgICAgIG1heF90ZW1wID0gbWF4KHRlbXAsIG5hLnJtID0gVCkpICU+JSAKICByaWdodF9qb2luKGRsbm1fZGF0YSwgYnkgPSBqb2luX2J5KCJkYXRlIiA9PSAiY29sbGVjdGlvbl9kYXRlIikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBtYXhfdGVtcCwgeSA9IG1lYW5fY3RtYXgpKSArIAogIGZhY2V0X3dyYXAoLn5zcF9uYW1lKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJnYW0iKSArIAogIGdlb21fcG9pbnQoKSArIAogIGxhYnMoeCA9ICJNYXggRGFpbHkgVGVtcC4gKMKwQykiLAogICAgICAgeSA9ICJNZWFuIENUbWF4ICjCsEMpIikgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUoc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpCmBgYAoKYGBge3Igc3VwcC1maWctZGxubS1wbG90fQoKc3BfbGlzdCA9IHVuaXF1ZShkbG5tX2RhdGEkc3BfbmFtZSkKCmZvcihsYWdfc3BlY2llcyBpbiBzcF9saXN0KXsKICAKICBkbG5tX2RhdGFfc3AgPSBkbG5tX2RhdGEgJT4lIAogICAgZmlsdGVyKHNwX25hbWUgPT0gbGFnX3NwZWNpZXMpCiAgCiAgIyBXZSBuZWVkIHRvIGVzdGltYXRlIGEgbWF0cml4IG9mIGV4cG9zdXJlIGhpc3RvcmllcyBmb3IgZWFjaCBvYnNlcnZhdGlvbi4gVGhpcyBjb250YWlucyB0aGUgc2VyaWVzIG9mIGV4cG9zdXJlcyBhdCBlYWNoIGxhZyAobCkgZm9yIGVhY2ggb2YgdGhlIG4gb2JzZXJ2YXRpb25zLCBjb25zdHJhaW5lZCBiZXR3ZWVuIGwwIChtaW5pbXVtIGxhZykgYW5kIEwgKG1heCBsYWcpLiAKICAKICBkYXRlcyA9IGRsbm1fZGF0YV9zcCRjb2xsZWN0aW9uX2RhdGUgIyBGb3IgZWFjaCBvZiB0aGVzZSBkYXRlcywgbWFrZSBhIHZlY3RvciBvZiB0aGUgcGFzdCAzMCBkYXlzIChpbmNsdWRpbmcgdGhlIGRheSBvZiBjb2xsZWN0aW9uKS4gTk9URTogRG9uJ3QgdXNlICd1bmlxdWUnIGRhdGVzIGhlcmUgc2luY2Ugc29tZSBjb2xsZWN0aW9ucyBoYWQgbXVsdGlwbGUgc3BlY2llcwogIAogIGV4cF9oaXN0X3ogPSBkYXRhLmZyYW1lKCkKICBleHBfaGlzdF90cmVuZCA9IGRhdGEuZnJhbWUoKQogIAogIGZvcihkIGluIGRhdGVzKXsKICAgIAogICAgaGlzdG9yeSA9IGxhZ190ZW1wcyAlPiUgCiAgICAgIGZpbHRlcihkYXRlIDw9IGQgJiBkYXRlID4gZCAtIDEwKSAlPiUgCiAgICAgIGFycmFuZ2UoZGVzYyhkYXRlKSwgZGVzYyhob3VyKSkgJT4lIAogICAgICBtdXRhdGUobGFnID0gcm93X251bWJlcigpIC0gMSkgJT4lIAogICAgICBzZWxlY3QobGFnLCBtZWFuX3RlbXAsIHRlbXBfZGlmZikKICAgIAogICAgel92ZWMgPSBzY2FsZShoaXN0b3J5JG1lYW5fdGVtcClbLDFdCiAgICBuYW1lcyh6X3ZlYykgPSBoaXN0b3J5JGxhZwogICAgCiAgICB0cmVuZF92ZWMgPSBoaXN0b3J5JHRlbXBfZGlmZgogICAgbmFtZXModHJlbmRfdmVjKSA9IGhpc3RvcnkkbGFnCiAgICAKICAgIGV4cF9oaXN0X3ogPSBiaW5kX3Jvd3MoZXhwX2hpc3Rfeiwgel92ZWMpCiAgICBleHBfaGlzdF90cmVuZCA9IGJpbmRfcm93cyhleHBfaGlzdF90cmVuZCwgdHJlbmRfdmVjKQogICAgCiAgfQogIAogICNwcmludChtYXgoZXhwX2hpc3RfdHJlbmQsIG5hLnJtID0gVCkpCiAgCiAgIyBUaGUgY3Jvc3MtYmFzaXMgZnVuY3Rpb24gZnJvbSBkbG5tIHdpbGwgdXNlIHRoZSBjbGFzcyBvZiB0aGUgeCBwYXJhbWV0ZXIgdG8gZGV0ZXJtaW5lIHdoYXQgdG8gZG8uIEluIG91ciBjYXNlLCB3ZSBuZWVkIHRvIHByb3ZpZGUgaXQgd2l0aCB0aGUgbWF0cml4IG9mIGV4cG9zdXJlIGhpc3RvcmllcyBmb3IgcmVhY2ggb2JzZXJ2YXRpb24gKHJvdykgYW5kIGxhZyAoY29sdW1uKS4gCiAgCiAgY2JfdGVtcHMgPSBjcm9zc2Jhc2lzKGV4cF9oaXN0X3RyZW5kLCBsYWcgPSBjKDAsZGltKGV4cF9oaXN0X3RyZW5kKVsyXS0xKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3ZhciA9bGlzdChmdW49ImNyIixkZj0zKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ2xhZz1saXN0KGZ1bj0iY3IiLGRmPTMsaW50ZXJjZXB0PVQpKQogIAogICNzdW1tYXJ5KGNiX3RlbXBzKQogIAogIHBlbmFsaXplZF9tYXQgPC0gY2JQZW4oY2JfdGVtcHMpCiAgCiAgI2ZpdHRpbmcgR0FNCiAgbGFnLmdhbSA9IGdhbShkYXRhID0gZGxubV9kYXRhX3NwLCAKICAgICAgICAgICAgICAgIG1lYW5fY3RtYXggfiBjb2xsZWN0aW9uX3RlbXAgKyBjYl90ZW1wcywgCiAgICAgICAgICAgICAgICBtZXRob2QgPSAiR0NWLkNwIiwKICAgICAgICAgICAgICAgIHBhcmFQZW49bGlzdChjYl90ZW1wcz1wZW5hbGl6ZWRfbWF0KSkKICAKICAjIHN1bW1hcnkobGFnLmdhbSkKICAjIEFJQyhsYWcuZ2FtKQogIAogICNlc3RpbWF0aW9uIG9mIGV4cG9zdXJlcyBlZmZlY3RzCiAgCiAgI2RlZmF1bHQgcGxvdHMKICBwcmVkX2dhbV9aczwtY3Jvc3NwcmVkKGNiX3RlbXBzLCBsYWcuZ2FtLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGN1bXVsPUYsIGNlbj0wLCBjaS5sZXZlbCA9IDAuOTUsCiAgICAgICAgICAgICAgICAgICAgICAgICBhdD1zZXEoLTQsNCwgMC4xKSkKICAKICBwbG90KHByZWRfZ2FtX1pzLCAiY29udG91ciIsIG1haW4gPSBsYWdfc3BlY2llcywgCiAgICAgICAgICAgICAgeGxhYiA9ICJUZW1wZXJhdHVyZSBEZXZpYXRpb24gKMKwQykiLCAKICAgICAgICAgICAgICB5bGFiID0gIkhvdXJzIGJlZm9yZSBjb2xsZWN0aW9uIikKICAKICAKICAjIAogICMgcGxvdChwcmVkX2dhbV9acywgYm9yZGVyID0gMiwgY3VtdWw9RiwKICAjICAgICAgIHRoZXRhPTExMCxwaGk9MjAsbHRoZXRhPS04MCkKICAKICAjIHBsb3QocHJlZF9nYW1fWnMsICJzbGljZXMiLAogICMgICAgICB2YXIgPSBjKDMsLTMpLAogICMgICAgICBsYWcgPSBjKDEsMjAwKSwKICAjICAgICAgY29sID0gMikKICAjIAp9CgoKYGBgCgoKIyMgTWlzY2VsbGFueQoKCmBgYHtyIHN1cHAtZmlnLXJhbXAtcmF0ZSwgZmlnLndpZHRoID0gNywgZmlnLmhlaWdodD01fQpydW5fc3RhcnRzID0gdGVtcF9yZWNvcmQgJT4lIAogIGdyb3VwX2J5KHJ1bikgJT4lIAogIGZpbHRlcihtaW51dGVfcGFzc2VkIDw9IDMpICU+JSAKICBzdW1tYXJpc2Uoc3RhcnRfdGVtcCA9IG1lYW4odGVtcF9DKSkgJT4lIAogIG11dGF0ZSgidGVtcF9iaW4iID0gY3V0X251bWJlcihzdGFydF90ZW1wLCA0KSwKICAgICAgICAgdGVtcF9iaW4gPSBjYXNlX3doZW4oCiAgICAgICAgICAgdGVtcF9iaW4gPT0gIlsyLjcsOS4yNl0iIH4gIlsyLjfCsEMgLSA5LjI2wrBDXSIsCiAgICAgICAgICAgdGVtcF9iaW4gPT0gIig5LjI2LDEzLjldIiB+ICJbOS4yNsKwQyAtIDEzLjnCsENdIiwKICAgICAgICAgICB0ZW1wX2JpbiA9PSAiKDEzLjksMjFdIiB+ICJbMTMuOcKwQyAtIDIxwrBDXSIsCiAgICAgICAgICAgdGVtcF9iaW4gPT0gIigyMSwzMC41XSIgfiAiWzIxwrBDIC0gMzAuNcKwQ10iCiAgICAgICAgICkpCgpyYW1wX3JlY29yZDIgPSByYW1wX3JlY29yZCAlPiUgCiAgZ3JvdXBfYnkocnVuLCBtaW51dGVfaW50ZXJ2YWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9yYW1wID0gbWVhbihyYW1wX3Blcl9taW51dGUpKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBsZWZ0X2pvaW4ocnVuX3N0YXJ0cykgJT4lIAogIG11dGF0ZSh0ZW1wX2JpbiA9IGZjdF9yZW9yZGVyKHRlbXBfYmluLCBzdGFydF90ZW1wLCAuZnVuID0gbWVhbikpCgpnZ3Bsb3QocmFtcF9yZWNvcmQyLCBhZXMoeCA9IG1pbnV0ZV9pbnRlcnZhbCwgeSA9IG1lYW5fcmFtcCkpICsgCiAgZmFjZXRfd3JhcCh0ZW1wX2Jpbn4uKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMywgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMSwgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21faGV4KGFlcyhmaWxsID0gY3V0KC4uY291bnQuLiwgYygyLCA1LCAxMCwgMjAsIDMwLCA0MCwgNTApKSksCiAgICAgICAgICAgYmlucyA9IDMwKSArIAogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKG5hbWU9Ik51bWJlciBvZiBPYnNlcnZhdGlvbnMiLAogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIjw1IiwgIjUtOSIsICIxMC0xOSIsICIyMC0yOSIsICIzMC0zOSIsICI0MC01MCIpLAogICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbiA9ICJtYWtvIikgKyAKICBsYWJzKHkgPSAiUmFtcCBSYXRlIChkZWcuIEMgLyBtaW4uKSIsCiAgICAgICB4ID0gIlRpbWUgaW50byBydW4gKG1pbnV0ZSkiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKGJhc2Vfc2l6ZSA9IDEyKQpgYGAKCgoKCgoKYGBge3J9CgppZihwcmVkaWN0X3Z1bG4gPT0gRil7CgogIGtuaXRyOjprbml0X2V4aXQoKQoKfQoKYGBgCgojIyBIaW5kY2FzdGluZyB2dWxuZXJhYmlsaXR5IHdpdGggZGlmZmVyZW50IGFjY2xpbWF0aW9uIHNjZW5hcmlvcwpVc2luZyB0aGUgb2JzZXJ2ZWQgdGhlcm1hbCBsaW1pdCBkYXRhLCB3ZSBjYW4gcHJvZHVjZSBhIGhpbmRjYXN0IG9mIHRoZXJtYWwgc3RyZXNzIGZvciBMYWtlIENoYW1wbGFpbiBjb3BlcG9kcy4gRm9yIHRoZXNlIGluaXRpYWwgYXNzYXlzLCB3ZSB3aWxsIGRlZmluZSB0aGVybWFsIHN0cmVzcyBhcyBhbnkgdGltZSB3aGVuIG1heGltdW0gZGFpbHkgd2F0ZXIgdGVtcGVyYXR1cmUgaXMgd2l0aGluIDXCsEMgb2YgY29wZXBvZCBDVG1heCBvciBoaWdoZXIgKGkuZS4gd2FybWluZyB0b2xlcmFuY2UgaXMgbGVzcyB0aGFuIDXCsEMpLiBXZSB3aWxsIHVzZSB0aHJlZSBkaWZmZXJlbnQgc2NlbmFyaW9zOiAxKSBlYWNoIHNwZWNpZXMgaGFzIGEgdW5pcXVlIGJ1dCBmaXhlZCB0aGVybWFsIGxpbWl0IChhdmVyYWdlIG1lYXN1cmVkIENUbWF4KSwgMikgc3BlY2llcyBoYXZlIHVuaXF1ZSB0aGVybWFsIGxpbWl0cyBhbmQgYXJlIGFibGUgdG8gYWNjbGltYXRlIChjb25zdGFudCBBUlIgYWNyb3NzIGFsbCBzcGVjaWVzIHVzZWQgdG8gcHJlZGljdCBDVG1heCBiYXNlZCBvbiBhdmVyYWdlIGRhaWx5IHRlbXBlcmF0dXJlcyksIGFuZCAzKSBzcGVjaWVzIGhhdmUgdW5pcXVlIHRoZXJtYWwgbGltaXRzIGFuZCBzcGVjaWVzLXNwZWNpZmljIGFjY2xpbWF0aW9uIChDVG1heCBwcmVkaWN0ZWQgdXNpbmcgd2hpY2hldmVyIGVudmlyb25tZW50YWwgZmFjdG9yIGFuZCBkdXJhdGlvbiBpcyB0aGUgc3Ryb25nZXN0IGNhbmRpZGF0ZSBmb3IgZHJpdmluZyBhY2NsaW1hdGlvbiAtIGZyb20gdGhlIGNvcnJlbGF0aW9uIGFuYWx5c2lzKS4gSW4gYWxsIGNhc2VzLCBkYXRhIGlzIGZpbHRlcmVkIHRvIGp1c3QgdGhlcm1hbCBsaW1pdHMgb2YgYWR1bHQgZmVtYWxlcy4gCgojIyMgU2NlbmFyaW8gMQpgYGB7cn0KbWVhbl9jdG1heCA9IGZ1bGxfZGF0YSAlPiUgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lICAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgCiAgc3VtbWFyaXplKCJtZWFuX2N0bWF4IiA9IG1lYW4oY3RtYXgpKSAlPiUgCiAgYXJyYW5nZShtZWFuX2N0bWF4KQoKa25pdHI6OmthYmxlKG1lYW5fY3RtYXgpCmBgYAoKYGBge3J9CiMgIyBDb25zdHJ1Y3RzIHRoZSBVUkwgZm9yIHRoZSBmdWxsIHRlbXBlcmF0dXJlIGRhdGEgc2V0OyBSVU4gVEhJUyBPTkNFCiMgaGluZF91cmwgPSBjb25zdHJ1Y3ROV0lTVVJMKHNpdGVOdW1iZXJzID0gc2l0ZU51bWJlciwgcGFyYW1ldGVyQ2QgPSBwYXJhbWV0ZXJDZCwgc2VydmljZSA9ICJ1diIpCiMgCiMgaGluZF90ZW1wX2RhdGEgPSBpbXBvcnRXYXRlck1MMShoaW5kX3VybCwgYXNEYXRlVGltZSA9IFQpICU+JQojICAgbXV0YXRlKCJkYXRlIiA9IGFzLkRhdGUoZGF0ZVRpbWUpKSAlPiUKIyAgIHNlbGVjdChkYXRlLCAidGVtcCIgPSBYXzAwMDEwXzAwMDAwKQojIAojIHdyaXRlLnRhYmxlKHggPSBoaW5kX3RlbXBfZGF0YSwgZmlsZSA9ICJoaW5kY2FzdF90ZW1wcy5jc3YiLCByb3cubmFtZXMgPSBGLCBzZXAgPSAiLCIpCmBgYAoKYGBge3J9CiMgZ2dwbG90KGhpbmRfdGVtcF9kYXRhLCBhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wKSkgKyAKIyAgIGdlb21fbGluZShsaW5ld2lkdGggPSAwLjEpICsgCiMgICBsYWJzKHggPSAiRGF0ZSIsIAojICAgICAgICB5ID0gIldhdGVyIFRlbXBlcmF0dXJlICjCsEMpIikgKwojICAgdGhlbWVfbWF0dCgpCmBgYAoKSW4gdGhlIHNpbXBsZXN0IHNjZW5hcmlvLCBzcGVjaWVzIHRoZXJtYWwgbGltaXRzIGFyZSBzdGF0aWMgdGhyb3VnaCB0aW1lLCByZXByZXNlbnRlZCBieSB0aGUgYXZlcmFnZSBDVG1heCBvZiBhZHVsdCBmZW1hbGUgY29wZXBvZHMuIEluIHRoaXMgc2NlbmFyaW8sIG9ubHkgdGhyZWUgb2YgdGhlIHNldmVuIG9ic2VydmVkIHNwZWNpZXMgYXJlIGV4cG9zZWQgdG8gdGhlcm1hbCBzdHJlc3MgKHRlbXBlcmF0dXJlcyB3aXRoaW4gNcKwQyBvZiBDVG1heCkuIFRlbXBlcmF0dXJlcyBhcHByb2FjaGVkIHRoZSB0aGVybWFsIGxpbWl0IG9mICpMZXB0b2RpYXB0b211cyBzaWNpbGlzKiBvbiBhIGhhbmRmdWwgb2YgZGF5cy4gQnkgY29udHJhc3QsICpTZW5lY2VsbGEgY2FsYW5vaWRlcyogYW5kICpMaW1ub2NhbGFudXMgbWFjcnVydXMqIHdlcmUgYm90aCBleHBvc2VkIHRvIHN1YnN0YW50aWFsIHRoZXJtYWwgc3RyZXNzIHRocm91Z2hvdXQgYSBsYXJnZSBwb3J0aW9uIG9mIHRoZSB5ZWFyLCBsaWtlbHkgZXhwbGFpbmluZyB3aHkgdGhlc2Ugc3BlY2llcyBhcmUgYWJzZW50IGZyb20gdGhlIGNvbW11bml0eSBmb3IgdGhlIHN1bW1lciBhbmQgZmFsbCBwZXJpb2RzLiAKCmBgYHtyIHN1cHAtZmlnLWhpbmQxX3NjZW5hcmlvLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NX0KaGluZDFfZGF0YSA9IGhpbmRfdGVtcF9kYXRhICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXplKCJkYWlseV9tYXgiID0gbWF4KHRlbXApLAogICAgICAgICAgICAiZGFpbHlfbWVhbiIgPSBtZWFuKHRlbXApLCkgJT4lIAogIGJpbmRfY29scyhwaXZvdF93aWRlcihtZWFuX2N0bWF4LCBuYW1lc19mcm9tID0gc3BfbmFtZSwgdmFsdWVzX2Zyb20gPSBtZWFuX2N0bWF4KSkgJT4lICAKICBwaXZvdF9sb25nZXIoY29scyA9IGMoLWRhdGUsIC1kYWlseV9tYXgsIC1kYWlseV9tZWFuKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAic3BlY2llcyIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAibWVhbl9jdG1heCIpICU+JSAgCiAgbXV0YXRlKGxpbV9kaWZmID0gbWVhbl9jdG1heCAtIGRhaWx5X21heCkgJT4lICAKICBtdXRhdGUoZG95ID0geWRheShkYXRlKSwKICAgICAgICAgIm1ldGhvZCIgPSAiTm9fYWNjbGltYXRpb24iKQoKaGluZF9kYWlseV90ZW1wX2RhdGEgPSBoaW5kX3RlbXBfZGF0YSAlPiUKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl90ZW1wID0gbWVhbih0ZW1wKSwKICAgICAgICAgICAgbWVkX3RlbXAgPSBtZWRpYW4odGVtcCksCiAgICAgICAgICAgIHZhcl90ZW1wID0gdmFyKHRlbXApLCAKICAgICAgICAgICAgbWluX3RlbXAgPSBtaW4odGVtcCksIAogICAgICAgICAgICBtYXhfdGVtcCA9IG1heCh0ZW1wKSkgJT4lIAogIG11dGF0ZSgicmFuZ2VfdGVtcCIgPSBtYXhfdGVtcCAtIG1pbl90ZW1wKQoKI3RhYmxlKGhpbmQxX2RhdGEkc3BlY2llcykKCmhpbmQxX2RhdGEgJT4lIAogIGZpbHRlcihsaW1fZGlmZiA8PSA1KSAlPiUgIAogIGdncGxvdChhZXMoeCA9IGRveSwgeSA9IGxpbV9kaWZmLCBjb2xvdXIgPSBzcGVjaWVzKSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNSwgCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleSIpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKwogIGdlb21fc21vb3RoKHNlID0gRikgKyAKICBsYWJzKHggPSAiRGF5IG9mIFllYXIiLCAKICAgICAgIHkgPSAiUHJlZGljdGVkIFdhcm1pbmcgVG9sZXJhbmNlIFxuKMKwQyBBYm92ZSBEYWlseSBNYXgpIikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQpgYGAKCiMjIyBTY2VuYXJpbyAyCkluIHRoZSBzZWNvbmQgc2NlbmFyaW8sIHRoZXJtYWwgbGltaXRzIHZhcnkgd2l0aGluIGFuZCBiZXR3ZWVuIHNwZWNpZXMuIEEgc2ltcGxlIG1vZGVsIGlzIHVzZWQgdG8gcHJlZGljdCBzcGVjaWVzIHRoZXJtYWwgbGltaXRzIGJhc2VkIG9uIG1lYW4gZGFpbHkgdGVtcGVyYXR1cmUgKENUbWF4IGFzIGEgZnVuY3Rpb24gb2Ygc3BlY2llcyBhbmQgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSwgYnV0IHdpdGhvdXQgdGhlIGludGVyYWN0aW9uIGJldHdlZW4gdGhlc2UgdHdvIGZhY3RvcnMpLiBUaGVzZSBwcmVkaWN0ZWQgdGhlcm1hbCBsaW1pdHMgYXJlIHRoZW4gY29tcGFyZWQgYWdhaW5zdCB0aGUgbWF4aW11bSBkYWlseSB0ZW1wZXJhdHVyZSB0byBlc3RpbWF0ZSB0aGVybWFsIHN0cmVzcywgYXMgaW4gU2NlbmFyaW8gMS4gSW5jbHVkaW5nIHRoaXMgc2ltcGxlIGZvcm0gb2YgYWNjbGltYXRpb24gaW4gdGhlIG1vZGVsIHJlZHVjZWQgdGhlIGRlZ3JlZSBvZiB0aGVybWFsIHN0cmVzcyBmb3IgZWFjaCBzcGVjaWVzLCBlbGltaW5hdGluZyBpdCBlbnRpcmVseSBmb3IgKkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMqLiBOb3RlIHRoYXQgdGhlIG1hZ25pdHVkZSBvZiB0aGUgcHJlZGljdGVkIHN0cmVzcyBpcyAgbG93IGVub3VnaCB0aGF0IHJlbW92aW5nIHRoZSA1wrBDIGJ1ZmZlciBhcm91bmQgdGhlIHByZWRpY3RlZCB0aGVybWFsIGxpbWl0cyB3b3VsZCBhY3R1YWxseSBsaW1pdCBwcmVkaWN0ZWQgdGhlcm1hbCBzdHJlc3MgdG8ganVzdCBhIGZldyBkYXlzIGZvciAqU2VuZWNlbGxhIGNhbGFub2lkZXMqLiAKCmBgYHtyIHN1cHAtZmlnLWhpbmQyX3NjZW5hcmlvLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD0xMH0KaGluZGNhc3RfbW9kZWwxID0gbG0oZGF0YSA9IGZpbHRlcihmdWxsX2RhdGEsIHNleCA9PSAiZmVtYWxlIiksCiAgICAgICAgICAgICAgICAgICAgIGN0bWF4IH4gY29sbGVjdGlvbl90ZW1wICsgc3BfbmFtZSkKCmhpbmQyX2RhdGEgPSBoaW5kX3RlbXBfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcml6ZSgiY29sbGVjdGlvbl90ZW1wIiA9IG1lYW4odGVtcCksCiAgICAgICAgICAgICJkYWlseV9tYXgiID0gbWF4KHRlbXApKSAlPiUgCiAgYmluZF9jb2xzKAogICAgcGl2b3Rfd2lkZXIobWVhbl9jdG1heCwgCiAgICAgICAgICAgICAgICBuYW1lc19mcm9tID0gc3BfbmFtZSwgCiAgICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IG1lYW5fY3RtYXgpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlLCAtZGFpbHlfbWF4LCAtY29sbGVjdGlvbl90ZW1wKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAic3BfbmFtZSIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAibWVhbl9jdG1heCIpICU+JSAKICBzZWxlY3QoLW1lYW5fY3RtYXgpICU+JSAKICBtdXRhdGUoInByZWRfY3RtYXgiID0gcHJlZGljdC5sbSAoaGluZGNhc3RfbW9kZWwxLCBuZXdkYXRhID0gLikpICU+JSAKICBzZWxlY3QoZGF0ZSwgImRhaWx5X21lYW4iID0gY29sbGVjdGlvbl90ZW1wLCBkYWlseV9tYXgsICJzcGVjaWVzIiA9IHNwX25hbWUsIHByZWRfY3RtYXgpICU+JSAKICBtdXRhdGUobGltX2RpZmYgPSBwcmVkX2N0bWF4IC0gZGFpbHlfbWF4KSAlPiUgCiAgI2ZpbHRlcihsaW1fZGlmZiA8PSAwKSAlPiUgIAogIG11dGF0ZShkb3kgPSB5ZGF5KGRhdGUpLAogICAgICAgICAibWV0aG9kIiA9ICJDb25zdGFudF9hY2NsaW1hdGlvbiIpCgojIGdncGxvdChoaW5kMl9kYXRhLCBhZXMoeCA9IGRhaWx5X21lYW4sIHkgPSBwcmVkX2N0bWF4LCBjb2xvdXIgPSBzcGVjaWVzKSkgKwojICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgCgojIHRhYmxlKGhpbmQyX2RhdGEkc3BlY2llcykKaGluZDJfZGF0YSAlPiUgIAogIGZpbHRlcihsaW1fZGlmZiA8PSA1KSAlPiUgIAogIGdncGxvdChhZXMoeCA9IGRveSwgeSA9IGxpbV9kaWZmLCBjb2xvdXIgPSBzcGVjaWVzKSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNSwgCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleSIpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKwogIGdlb21fc21vb3RoKCkgKyAKICBsYWJzKHggPSAiRGF5IG9mIFllYXIiLCAKICAgICAgIHkgPSAiUHJlZGljdGVkIFdhcm1pbmcgVG9sZXJhbmNlIFxuKMKwQyBBYm92ZSBEYWlseSBNYXgpIikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQpgYGAKCiMjIyBTY2VuYXJpbyAzClRoZSBmaW5hbCBzY2VuYXJpbyBhbGxvd3MgdGhlIGVudmlyb25tZW50YWwgdmFyaWFibGUgdXNlZCB0byBwcmVkaWN0IENUbWF4IHRvIHZhcnkgYmV0d2VlbiBzcGVjaWVzLiBGb3Igc3BlY2llcyBvYnNlcnZlZCBpbiBmZXdlciB0aGFuIDUgY29sbGVjdGlvbnMsIHdlIHVzZSB0aGUgc2FtZSBhcHByb2FjaCBhcyBpbiBTY2VuYXJpbyAyLiBGb3Igc3BlY2llcyBvYnNlcnZlZCBpbiBtb3JlIHRoYW4gNSBjb2xsZWN0aW9ucywgaG93ZXZlciwgdGhlIGZhY3RvciB3aXRoIHRoZSBzdHJvbmdlc3QgY29ycmVsYXRpb24gd2l0aCBDVG1heCBpcyB1c2VkIHRvIHByZWRpY3QgdGhlcm1hbCBsaW1pdHMuIFRoZXNlIGZhY3RvcnMgYXJlIGluY2x1ZGVkIGJlbG93LgoKYGBge3J9CmhpbmRfcHJlZHMgPSBjb3JyX3ZhbHMgJT4lICAKICBmaWx0ZXIoc2lnID09ICJTaWcuIikgJT4lIAogIGRyb3BfbmEoY29ycmVsYXRpb24pICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUKICBhcnJhbmdlKGRlc2MoY29ycmVsYXRpb24pKSAlPiUgCiAgc2xpY2VfaGVhZChuID0gMSkgJT4lIAogIHNlbGVjdCgiU3BlY2llcyIgPSBzcF9uYW1lLCAiUHJlZGljdG9yIiA9IHBhcmFtZXRlciwgIkR1cmF0aW9uIiA9IGR1cmF0aW9uLCAiQ29ycmVsYXRpb24iID0gY29ycmVsYXRpb24sICJQLVZhbHVlIiA9IHAudmFsdWUpCgprbml0cjo6a2FibGUoaGluZF9wcmVkcywgYWxpZ24gPSAiYyIpCmBgYAoKYGBge3J9CmhpbmQzX2RhdGEgPSBoaW5kMl9kYXRhICU+JSAjIENvbnRhaW5zIGRhdGEgZm9yIHNwZWNpZXMgdGhhdCB3b24ndCBjaGFuZ2UgZnJvbSBzY2VuYXJpbyAyCiAgZmlsdGVyKCEoc3BlY2llcyAlaW4lIGNvcnJfdmFscyRzcF9uYW1lKSkKCnByZWRzX3RvX3B1bGwgPSBoaW5kX3ByZWRzICU+JSAgCiAgc2VsZWN0KFNwZWNpZXMsIFByZWRpY3RvciwgRHVyYXRpb24pIAoKZm9yKGkgaW4gMTpsZW5ndGgocHJlZHNfdG9fcHVsbCRTcGVjaWVzKSl7CiAgCiAgZHVyYXRpb24gPSBwcmVkc190b19wdWxsJER1cmF0aW9uW2ldCiAgCiAgaWYoZHVyYXRpb24gPT0gMCl7ICNUaGUgcHJpb3IgZGF5IHRlbXBlcmF0dXJlIG1ldHJpY3Mgc2hvdWxkIGJlIHVzZWQKICAgIAogICAgcHJlZGljdG9ycyA9IGhpbmRfZGFpbHlfdGVtcF9kYXRhICU+JSAKICAgICAgbXV0YXRlKGRhdGUgPSBkYXRlKSAKICAgIAogICAgcGFyYW1ldGVyID0gIm1lYW5fdGVtcCIgI3VzaW5nIG1lYW4gdGVtcGVyYXR1cmUgYXMgYSBwcm94eSBmb3IgY29sbGVjdGlvbiB0ZW1wCiAgICAKICAgIG1vZGVsX2RhdGEgPSBmdWxsX2RhdGEgJT4lCiAgICAgIGZpbHRlcihzcF9uYW1lICVpbiUgcHJlZHNfdG9fcHVsbCRTcGVjaWVzW2ldKSAlPiUgCiAgICAgIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICAgICAgbXV0YXRlKGNvbGxlY3Rpb25fZGF0ZSA9IGFzX2RhdGUoY29sbGVjdGlvbl9kYXRlKSkgJT4lIAogICAgICBpbm5lcl9qb2luKHByZWRpY3RvcnMsIGpvaW5fYnkoY29sbGVjdGlvbl9kYXRlID09IGRhdGUpKSAlPiUgIAogICAgICBzZWxlY3QoY3RtYXgsIGNvbnRhaW5zKHBhcmFtZXRlcikpCiAgICAKICAgIGlmKGRpbShtb2RlbF9kYXRhKVsyXSA9PSAyKXsKICAgICAgaGluZC5tb2RlbCA9IGxtKGRhdGEgPSBtb2RlbF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgIGN0bWF4IH4gLikKICAgICAgCiAgICAgIHNwX2RhdGEgPSBwcmVkaWN0b3JzICU+JSAKICAgICAgICBzZWxlY3QoZGF0ZSwgY29udGFpbnMocGFyYW1ldGVyKSkgJT4lIAogICAgICAgIG11dGF0ZShwcmVkX2N0bWF4ID0gcHJlZGljdChoaW5kLm1vZGVsLCBuZXdkYXRhID0gLikpICU+JSAgCiAgICAgICAgc2VsZWN0KGRhdGUsIHByZWRfY3RtYXgpICU+JSAKICAgICAgICBpbm5lcl9qb2luKGhpbmRfZGFpbHlfdGVtcF9kYXRhLCBieSA9IGMoImRhdGUiKSkgJT4lIAogICAgICAgIG11dGF0ZSgic3BlY2llcyIgPSBwcmVkc190b19wdWxsJFNwZWNpZXNbaV0sCiAgICAgICAgICAgICAgICJkb3kiID0geWRheShkYXRlKSwKICAgICAgICAgICAgICAgbGltX2RpZmYgPSBwcmVkX2N0bWF4IC0gbWF4X3RlbXApICU+JSAKICAgICAgICBzZWxlY3QoZGF0ZSwgZGFpbHlfbWVhbiA9IG1lYW5fdGVtcCwgZGFpbHlfbWF4ID0gbWF4X3RlbXAsIHNwZWNpZXMsIHByZWRfY3RtYXgsIGxpbV9kaWZmLCBkb3kpCiAgICAgIAogICAgICBoaW5kM19kYXRhID0gYmluZF9yb3dzKGhpbmQzX2RhdGEsIHNwX2RhdGEpCiAgICB9ZWxzZXsKICAgICAgcHJpbnQoYyh1bmlxdWUoc3BfZGF0YSRzcGVjaWVzKSwgIlRvbyBtYW55IGNvbHVtbnMgc2VsZWN0ZWQiKSkKICAgIH0KICAgIAogIH0KICAKICBpZihkdXJhdGlvbiA+IDApewogICAgI05laXRoZXIgdGhlIHByaW9yIGRheSBub3IgZGF5IG9mIG1ldHJpY3Mgc2hvdWxkIGJlIHVzZWQ7IHVzZSBkdXJhdGlvbiBhcyBuX2RheXMKICAgIAogICAgcHJlZGljdG9ycyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGhpbmRfZGFpbHlfdGVtcF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IGhpbmRfdGVtcF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSBkdXJhdGlvbikKICAgIAogICAgcGFyYW1ldGVyID0gcHJlZHNfdG9fcHVsbCRQcmVkaWN0b3JbaV0KICAgIAogICAgbW9kZWxfZGF0YSA9IGZ1bGxfZGF0YSAlPiUKICAgICAgZmlsdGVyKHNwX25hbWUgJWluJSBwcmVkc190b19wdWxsJFNwZWNpZXNbaV0pICU+JSAKICAgICAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogICAgICBtdXRhdGUoY29sbGVjdGlvbl9kYXRlID0gYXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgICAgIGxlZnRfam9pbihwcmVkaWN0b3JzLCBqb2luX2J5KGNvbGxlY3Rpb25fZGF0ZSA9PSBkYXRlKSkgJT4lICAKICAgICAgc2VsZWN0KGN0bWF4LCBjb250YWlucyhwYXN0ZSgiZGF5XyIsIHBhcmFtZXRlciwgc2VwID0gIiIpKSkKICAgIAogICAgaWYoZGltKG1vZGVsX2RhdGEpWzJdID09IDIpewogICAgICBoaW5kLm1vZGVsID0gbG0oZGF0YSA9IG1vZGVsX2RhdGEsIAogICAgICAgICAgICAgICAgICAgICAgY3RtYXggfiAuKQogICAgICAKICAgICAgc3BfZGF0YSA9IHByZWRpY3RvcnMgJT4lIAogICAgICAgIHNlbGVjdChkYXRlLCBjb250YWlucyhwYXJhbWV0ZXIpKSAlPiUgCiAgICAgICAgbXV0YXRlKHByZWRfY3RtYXggPSBwcmVkaWN0KGhpbmQubW9kZWwsIG5ld2RhdGEgPSAuKSkgJT4lICAKICAgICAgICBzZWxlY3QoZGF0ZSwgcHJlZF9jdG1heCkgJT4lIAogICAgICAgIGlubmVyX2pvaW4oaGluZF9kYWlseV90ZW1wX2RhdGEsIGJ5ID0gYygiZGF0ZSIpKSAlPiUgCiAgICAgICAgbXV0YXRlKCJzcGVjaWVzIiA9IHByZWRzX3RvX3B1bGwkU3BlY2llc1tpXSwKICAgICAgICAgICAgICAgImRveSIgPSB5ZGF5KGRhdGUpLAogICAgICAgICAgICAgICBsaW1fZGlmZiA9IHByZWRfY3RtYXggLSBtYXhfdGVtcCkgJT4lIAogICAgICAgIHNlbGVjdChkYXRlLCBkYWlseV9tZWFuID0gbWVhbl90ZW1wLCBkYWlseV9tYXggPSBtYXhfdGVtcCwgc3BlY2llcywgcHJlZF9jdG1heCwgbGltX2RpZmYsIGRveSkKICAgICAgCiAgICAgIGhpbmQzX2RhdGEgPSBiaW5kX3Jvd3MoaGluZDNfZGF0YSwgc3BfZGF0YSkKICAgICAgCiAgICB9ZWxzZXsKICAgICAgcHJpbnQoYyh1bmlxdWUoc3BfZGF0YSRzcGVjaWVzKSwgIlRvbyBtYW55IGNvbHVtbnMgc2VsZWN0ZWQiKSkKICAgIH0KICAgIAogIH0KfQoKCmhpbmQzX2RhdGEgPSBoaW5kM19kYXRhICU+JSAKICBtdXRhdGUoIm1ldGhvZCIgPSAiVmFyaWFibGVfYWNjbGltYXRpb24iKQpgYGAKClRoaXMgdGhpcmQgYXBwcm9hY2ggZGlkIG5vdCBhZmZlY3QgdGhlIHByZWRpY3RlZCBwYXR0ZXJucyBpbiAqTGltbm9jYWxhbnVzKiBvciAqU2VuZWNlbGxhKiAobmVpdGhlciBzcGVjaWVzIGhhcyBiZWVuIG9ic2VydmVkIGluIGVub3VnaCBjb2xsZWN0aW9ucyB0byBlc3RpbWF0ZSB0aGUgZWZmZWN0cyBvZiBkaWZmZXJlbnQgZW52aXJvbm1lbnRhbCBmYWN0b3JzKS4gQ2hhbmdpbmcgdGhlIGFjY2xpbWF0aW9uIGFwcHJvYWNoIGRpZCBhZmZlY3QgcGF0dGVybnMgaW4gdGhlcm1hbCBsaW1pdHMgaW4gdGhlIG90aGVyIHNwZWNpZXMgdGhvdWdoLiBUaGUgZmlndXJlIGJlbG93IHNob3dzIGhvdyBwcmVkaWN0ZWQgd2FybWluZyB0b2xlcmFuY2UgdmFyaWVzIG92ZXIgdGhlIHllYXIgaW4gdGhlIHNldmVuIHNwZWNpZXMsIGJhc2VkIG9uIHRoZSB0aHJlZSBkaWZmZXJlbnQgcHJlZGljdGlvbiBtZXRob2RzLiBJbiBnZW5lcmFsLCBjb25zdGFudCB0aGVybWFsIGxpbWl0cyAodGhlICdubyBhY2NsaW1hdGlvbicgbWV0aG9kKSByZXN1bHRlZCBpbiBsYXJnZXIgd2FybWluZyB0b2xlcmFuY2UgZHVyaW5nIHRoZSB3aW50ZXIgYW5kIGxvd2VyIHdhcm1pbmcgdG9sZXJhbmNlIGR1cmluZyB0aGUgc3VtbWVyLCBhbHRob3VnaCB0aGlzIGVmZmVjdCB3YXMgc21hbGwgaW4gbW9zdCBzcGVjaWVzLiAgICAgCmBgYHtyIHN1cHAtZmlnLWhpbmRfY2FzdF9zdW1tYXJ5LCBmaWcud2lkdGg9MTMsIGZpZy5oZWlnaHQ9MTB9CnN5bnRoZXNpcyA9IGJpbmRfcm93cygKICBzZWxlY3QoaGluZDFfZGF0YSwgZGF0ZSwgZG95LCBkYWlseV9tZWFuLCBkYWlseV9tYXgsIHNwZWNpZXMsICJwcmVkX2N0bWF4IiA9IG1lYW5fY3RtYXgsIGxpbV9kaWZmLCBtZXRob2QpLAogIHNlbGVjdChoaW5kMl9kYXRhLCBkYXRlLCBkb3ksIGRhaWx5X21lYW4sIGRhaWx5X21heCwgIHNwZWNpZXMsIHByZWRfY3RtYXgsIGxpbV9kaWZmLCBtZXRob2QpLAogIHNlbGVjdChoaW5kM19kYXRhLCBkYXRlLCBkb3ksIGRhaWx5X21lYW4sIGRhaWx5X21heCwgIHNwZWNpZXMsIHByZWRfY3RtYXgsIGxpbV9kaWZmLCBtZXRob2QpKSAlPiUgCiAgbXV0YXRlKG1ldGhvZCA9IGZjdF9yZWxldmVsKG1ldGhvZCwgIk5vX2FjY2xpbWF0aW9uIiwgIkNvbnN0YW50X2FjY2xpbWF0aW9uIiwgIlZhcmlhYmxlX2FjY2xpbWF0aW9uIikpICU+JSAKICBmaWx0ZXIoIShzcGVjaWVzID09ICJPc3BocmFudGljdW0gbGFicm9uZWN0dW0iICYgbWV0aG9kID09ICJWYXJpYWJsZV9hY2NsaW1hdGlvbiIpKQoKY2xpbWF0b2xvZ3kgPSBzeW50aGVzaXMgJT4lIAogIGdyb3VwX2J5KHNwZWNpZXMsIGRveSwgbWV0aG9kKSAlPiUgIAogIHN1bW1hcmlzZSgibWVhbl9kaWZmIiA9IG1lYW4obGltX2RpZmYpLAogICAgICAgICAgICAibWluX2RpZmYiID0gbWluKGxpbV9kaWZmKSwKICAgICAgICAgICAgIm1heF9kaWZmIiA9IG1heChsaW1fZGlmZikpICU+JSAKICBtdXRhdGUobWV0aG9kID0gZmN0X3JlbGV2ZWwobWV0aG9kLCAiTm9fYWNjbGltYXRpb24iLCAiQ29uc3RhbnRfYWNjbGltYXRpb24iLCAiVmFyaWFibGVfYWNjbGltYXRpb24iKSkKCmFjY19lZmZlY3RzID0gc3ludGhlc2lzICU+JSAKICBwaXZvdF93aWRlcihpZF9jb2xzID0gYyhkYXRlLCBzcGVjaWVzLCBkb3kpLCAKICAgICAgICAgICAgICBuYW1lc19mcm9tID0gbWV0aG9kLCAKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IGxpbV9kaWZmKSAlPiUgIAogIG11dGF0ZSgiY29uc3RfYWNjX2VmZmVjdCIgPSBDb25zdGFudF9hY2NsaW1hdGlvbiAtIE5vX2FjY2xpbWF0aW9uLAogICAgICAgICAidmFyX2FjY19lZmZlY3QiID0gVmFyaWFibGVfYWNjbGltYXRpb24gLSBOb19hY2NsaW1hdGlvbikKCmdncGxvdChzeW50aGVzaXMsIGFlcyh4ID0gZG95LCB5ID0gbGltX2RpZmYsIGNvbG91ciA9IG1ldGhvZCkpICsgCiAgZmFjZXRfd3JhcChzcGVjaWVzfi4pICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LCBjb2xvdXIgPSAiZ3JleSIpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMSkgKyAKICBsYWJzKHggPSAiRGF5IG9mIFllYXIiLCAKICAgICAgIHkgPSAiUHJlZGljdGVkIFdhcm1pbmcgVG9sZXJhbmNlICjCsEMgQWJvdmUgRGFpbHkgTWF4KSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKGJhc2Vfc2l6ZSA9IDE4KSArIAogIHRoZW1lKHN0cmlwLnRleHQueC50b3AgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkKYGBgCgpgYGB7ciBzdXBwLWZpZy1hY2Nfc2NlbmFyaW9fZWZmZWN0cywgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9N30Kd3RfaGluZGNhc3Rfc3VtbWFyeSA9IHN5bnRoZXNpcyAlPiUgIAogIG11dGF0ZSgieWVhciIgPSB5ZWFyKGRhdGUpKSAlPiUgCiAgZ3JvdXBfYnkoc3BlY2llcywgeWVhciwgbWV0aG9kKSAlPiUgCiAgc3VtbWFyaXNlKCJtaW5fd3QiID0gbWluKGxpbV9kaWZmKSwKICAgICAgICAgICAgIm1heF93dCIgPSBtYXgobGltX2RpZmYpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKG1pbl93dCwgbWF4X3d0KSwgCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIm1ldHJpYyIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAid3QiKSAlPiUgCiAgZ3JvdXBfYnkoc3BlY2llcywgbWV0aG9kLCBtZXRyaWMpICU+JSAKICBzdW1tYXJpc2UoIm1lYW5fd3QiID0gbWVhbih3dCkpCgp3dF9oaW5kY2FzdF9zdW1tYXJ5ICU+JSAKICBmaWx0ZXIobWV0cmljID09ICJtaW5fd3QiKSAlPiUgCmdncGxvdChhZXMoeCA9IG1ldGhvZCwgeSA9IG1lYW5fd3QsIGdyb3VwID0gc3BlY2llcywgY29sb3VyID0gc3BlY2llcykpICsgCiAgI2ZhY2V0X3dyYXAoLn5tZXRyaWMsIHNjYWxlcyA9ICJmcmVlX3kiKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNSkgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIGxhYnMoeCA9ICJTY2VuYXJpbyIsIAogICAgICAgeSA9ICJNZWFuIFllYXJseSBNaW5pbXVtIFdUICjCsEMpIikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwMCwgaGp1c3QgPSAwLCB2anVzdCA9IDAuNSkpCmBgYAo=